<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>혁신을 이룹니다, 오딘박스</title>
    <link>https://odinbox.tistory.com/</link>
    <description>혁신을 이룹니다, 오딘박스(OdinBOX)</description>
    <language>ko</language>
    <pubDate>Mon, 29 Jun 2026 12:24:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>간지뽕빨리턴님</managingEditor>
    <image>
      <title>혁신을 이룹니다, 오딘박스</title>
      <url>https://tistory1.daumcdn.net/tistory/1569230/attach/0929e04b079a40c6b84b1715fd186fb3</url>
      <link>https://odinbox.tistory.com</link>
    </image>
    <item>
      <title>6.25전쟁 76주년, 우리가 평생 기억해야 할 이름들</title>
      <link>https://odinbox.tistory.com/591</link>
      <description>&lt;div class=&quot;kwar-wrap&quot;&gt;
&lt;style&gt;
    .kwar-wrap{
      max-width:860px;
      margin:0 auto;
      font-family:-apple-system,BlinkMacSystemFont,&quot;Noto Sans KR&quot;,&quot;Malgun Gothic&quot;,sans-serif;
      color:#262626;
      line-height:1.9;
      letter-spacing:-0.03em;
      word-break:keep-all;
    }
    .kwar-wrap *{box-sizing:border-box;}

    .kwar-visual{
      background:linear-gradient(180deg,#111 0%,#1d1d1d 52%,#f7f5f1 52%,#fff 100%);
      border-radius:26px;
      padding:34px 22px 18px;
      margin:0 0 34px;
      box-shadow:0 18px 42px rgba(0,0,0,.12);
      text-align:center;
    }
    .kwar-thumbnail{
      max-width:560px;
      margin:0 auto;
      padding:10px;
      background:rgba(255,255,255,.08);
      border:1px solid rgba(255,255,255,.18);
      border-radius:24px;
      box-shadow:0 16px 34px rgba(0,0,0,.28);
      overflow:hidden;
    }
    .kwar-thumbnail p{margin:0 !important;}
    .kwar-thumbnail img{
      border-radius:18px !important;
      display:block !important;
      margin:0 auto !important;
      max-width:100% !important;
      height:auto !important;
    }

    .kwar-hero{
      margin:28px auto 0;
      max-width:760px;
      background:linear-gradient(135deg,#151515 0%,#262626 100%);
      color:#fff !important;
      padding:42px 26px 38px;
      border-radius:24px;
      text-align:center;
      position:relative;
      overflow:hidden;
    }
    .kwar-hero:before{
      content:&quot;&quot;;
      position:absolute;
      top:0;
      left:50%;
      width:1px;
      height:100%;
      background:linear-gradient(to bottom,transparent,rgba(255,255,255,.16),transparent);
    }
    .kwar-date{
      display:inline-block;
      position:relative;
      z-index:1;
      font-size:14px;
      color:#e6e0d5 !important;
      border:1px solid rgba(255,255,255,.22);
      border-radius:999px;
      padding:7px 14px;
      margin-bottom:20px;
      background:rgba(255,255,255,.05);
    }
    .kwar-title{
      position:relative;
      z-index:1;
      margin:0 !important;
      font-size:36px !important;
      line-height:1.35 !important;
      font-weight:800 !important;
      color:#ffffff !important;
      letter-spacing:-0.05em;
    }
    .kwar-subtitle{
      position:relative;
      z-index:1;
      margin:18px auto 0 !important;
      max-width:650px;
      font-size:17px !important;
      line-height:1.85 !important;
      color:#f1f1f1 !important;
      font-weight:500;
    }
    .kwar-badges{
      position:relative;
      z-index:1;
      display:flex;
      justify-content:center;
      flex-wrap:wrap;
      gap:10px;
      margin-top:24px;
    }
    .kwar-badge{
      display:inline-block;
      padding:8px 13px;
      border-radius:999px;
      background:rgba(255,255,255,.1);
      color:#fff !important;
      font-size:13px;
      border:1px solid rgba(255,255,255,.16);
    }

    .kwar-lead{
      background:#fff;
      border:1px solid #ece7df;
      border-radius:22px;
      padding:30px 28px;
      margin:0 0 34px;
      box-shadow:0 12px 30px rgba(50,40,20,.06);
    }
    .kwar-p{
      margin:0 0 18px !important;
      font-size:17px !important;
      color:#333 !important;
      line-height:1.95 !important;
    }
    .kwar-p:last-child{margin-bottom:0 !important;}

    .kwar-section{
      margin:42px 0 0;
    }
    .kwar-section h2{
      margin:0 0 18px !important;
      font-size:27px !important;
      line-height:1.45 !important;
      color:#111 !important;
      font-weight:800 !important;
      border-left:5px solid #111;
      padding-left:15px;
    }
    .kwar-section h3{
      margin:0 0 12px !important;
      font-size:21px !important;
      color:#111 !important;
      font-weight:800 !important;
    }

    .kwar-card{
      background:#fff;
      border:1px solid #e8e2d9;
      border-radius:20px;
      padding:24px 24px;
      box-shadow:0 10px 26px rgba(0,0,0,.045);
      margin-top:18px;
    }
    .kwar-card.dark{
      background:linear-gradient(135deg,#151515,#252525);
      border-color:#222;
      color:#fff !important;
    }
    .kwar-card.dark h3,
    .kwar-card.dark p,
    .kwar-card.dark strong,
    .kwar-card.dark .kwar-p{
      color:#fff !important;
    }

    .kwar-fact{
      list-style:none;
      padding:0;
      margin:0;
    }
    .kwar-fact li{
      margin:0 0 14px;
      padding:0 0 14px;
      border-bottom:1px dashed #ddd6cc;
      font-size:16px;
      color:#333;
      line-height:1.8;
    }
    .kwar-fact li:last-child{
      margin-bottom:0;
      padding-bottom:0;
      border-bottom:0;
    }
    .kwar-fact strong{
      display:block;
      color:#111 !important;
      font-size:17px;
      margin-bottom:4px;
      font-weight:800;
    }

    .kwar-quote-box{
      margin:28px 0 !important;
      padding:30px 24px !important;
      background:linear-gradient(135deg,#171717,#282828) !important;
      color:#ffffff !important;
      border-radius:20px !important;
      text-align:center !important;
      font-size:21px !important;
      line-height:1.85 !important;
      font-weight:700 !important;
      box-shadow:0 12px 28px rgba(0,0,0,.14) !important;
      border:1px solid rgba(255,255,255,.12) !important;
    }
    .kwar-quote-box p{
      margin:0 !important;
      color:#ffffff !important;
      font-size:21px !important;
      line-height:1.85 !important;
      font-weight:700 !important;
    }
    .kwar-quote-box span{
      display:block;
      color:#cfcfcf !important;
      font-size:14px !important;
      font-weight:400 !important;
      margin-top:12px !important;
    }

    .kwar-grid{
      display:grid;
      grid-template-columns:repeat(2,minmax(0,1fr));
      gap:16px;
      margin-top:18px;
    }
    .kwar-mini{
      font-size:14px !important;
      color:#777 !important;
      margin:0 0 10px !important;
    }
    .kwar-country{
      display:block;
      font-size:15px;
      color:#444;
      line-height:1.85;
    }

    .kwar-vow{
      margin-top:22px;
      padding:30px 26px;
      border-radius:22px;
      background:linear-gradient(180deg,#fffaf0,#ffffff);
      border:1px solid #eadfcf;
      box-shadow:0 12px 30px rgba(80,60,30,.06);
    }
    .kwar-vow strong{
      color:#111 !important;
      font-weight:800;
    }

    .kwar-vow-grid{
      display:grid;
      grid-template-columns:repeat(3,minmax(0,1fr));
      gap:14px;
      margin-top:22px;
    }
    .kwar-vow-item{
      background:#fff;
      border:1px solid #e8e1d7;
      border-radius:18px;
      padding:20px 18px;
      text-align:center;
    }
    .kwar-vow-item strong{
      display:block;
      font-size:18px;
      color:#111 !important;
      margin-bottom:8px;
    }
    .kwar-vow-item span{
      display:block;
      font-size:14px;
      color:#555;
      line-height:1.75;
    }

    .kwar-ending{
      margin:48px 0 0;
      padding:42px 28px;
      border-radius:26px;
      background:linear-gradient(135deg,#151515 0%,#252525 100%);
      border:1px solid #222;
      text-align:center;
      color:#fff !important;
      box-shadow:0 16px 38px rgba(0,0,0,.16);
    }
    .kwar-ending strong{
      display:block;
      font-size:27px;
      color:#fff !important;
      margin-bottom:16px;
      line-height:1.55;
    }
    .kwar-ending p{
      margin:0 auto 16px !important;
      max-width:680px;
      font-size:16.5px !important;
      color:#f0f0f0 !important;
      line-height:1.95 !important;
    }
    .kwar-ending p:last-child{
      margin-bottom:0 !important;
    }
    .kwar-last-line{
      margin-top:24px !important;
      padding-top:22px;
      border-top:1px solid rgba(255,255,255,.18);
      font-size:18px !important;
      font-weight:700;
      color:#fff !important;
    }

    @media (max-width:768px){
      .kwar-visual{padding:24px 14px 14px;}
      .kwar-hero{padding:34px 20px 32px;}
      .kwar-title{font-size:29px !important;}
      .kwar-subtitle{font-size:15.5px !important;}
      .kwar-lead,.kwar-card,.kwar-vow{padding:22px 20px;}
      .kwar-section h2{font-size:23px !important;}
      .kwar-grid,.kwar-vow-grid{grid-template-columns:1fr;}
      .kwar-quote-box,
      .kwar-quote-box p{font-size:18px !important;}
      .kwar-ending strong{font-size:23px;}
    }
  &lt;/style&gt;
&lt;div class=&quot;kwar-visual&quot;&gt;
&lt;div class=&quot;kwar-thumbnail&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (5).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uh0TN/dJMb99Un8hO/jIfkXvfD1s57hfFjldGvI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uh0TN/dJMb99Un8hO/jIfkXvfD1s57hfFjldGvI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uh0TN/dJMb99Un8hO/jIfkXvfD1s57hfFjldGvI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUh0TN%2FdJMb99Un8hO%2FjIfkXvfD1s57hfFjldGvI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (5).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-hero&quot;&gt;
&lt;div class=&quot;kwar-date&quot;&gt;1950년 6월 25일 발발 &amp;middot; 2026년 6월 25일 76주년&lt;/div&gt;
&lt;h1 class=&quot;kwar-title&quot;&gt;6.25 전쟁 76주년,&lt;br /&gt;우리가 아직 기억해야 할 이름들&lt;/h1&gt;
&lt;p class=&quot;kwar-subtitle&quot; data-ke-size=&quot;size16&quot;&gt;총성은 오래전에 멈춘 듯 보이지만, 한반도는 아직 완전한 평화의 문턱을 넘지 못했습니다. 오늘은 지나간 전쟁을 떠올리는 날이 아니라, 참전용사들의 헌신 위에 세워진 자유 대한민국을 다시 마음에 새기는 날입니다.&lt;/p&gt;
&lt;div class=&quot;kwar-badges&quot;&gt;&lt;span class=&quot;kwar-badge&quot;&gt;6.25전쟁 76주년&lt;/span&gt; &lt;span class=&quot;kwar-badge&quot;&gt;참전용사의 헌신&lt;/span&gt; &lt;span class=&quot;kwar-badge&quot;&gt;자유 대한민국을 지키는 의지&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-lead&quot;&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;6월 25일은 유독 조용히 지나가는 날처럼 느껴질 때가 있습니다. 달력 속 숫자는 그대로인데, 그날을 기억하는 마음은 해마다 조금씩 옅어지는 것 같기도 합니다. 그러나 우리가 오늘 누리는 평범한 하루는 결코 처음부터 당연했던 것이 아니었습니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;누군가는 가족의 품을 떠나 전선으로 향했고, 누군가는 이름도 얼굴도 알지 못하는 나라의 자유를 지키기 위해 바다를 건너왔습니다. 그들이 지켜낸 것은 단지 한 땅의 경계가 아니었습니다. 그들이 지켜낸 것은 자유롭게 말하고, 일하고, 꿈꾸며, 다음 세대에게 더 나은 내일을 물려줄 수 있는 대한민국의 가능성이었습니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;그래서 6.25전쟁을 기억한다는 것은 과거의 아픔을 반복해서 꺼내는 일이 아닙니다. 그것은 참전용사들의 희생을 헛되이 하지 않겠다는 다짐이며, 자유 대한민국을 더 단단히 지켜가겠다는 우리의 의지를 확인하는 일입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;짧지만 반드시 기억해야 할 사실&lt;/h2&gt;
&lt;div class=&quot;kwar-card&quot;&gt;
&lt;ul class=&quot;kwar-fact&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;1950년 6월 25일&lt;/b&gt; 북한의 전면 남침으로 6.25 전쟁이 시작되었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;1953년 7월 27일&lt;/b&gt; 전쟁은 완전히 끝난 것이 아니라, 정전협정으로 전투가 멈춘 상태가 되었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유엔 참전국 22개국&lt;/b&gt; 전투지원 16개국과 의료지원 6개국이 대한민국을 지키기 위해 함께했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지금도 이어지는 정전의 시간&lt;/b&gt; 한반도는 아직 공식적인 평화조약이 체결된 상태가 아니라 정전 체제 아래에 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;숫자 뒤에 남아 있는 사람들&lt;/h2&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;전쟁을 이야기할 때 우리는 날짜와 숫자를 먼저 떠올립니다. 1950년 6월 25일, 1953년 7월 27일, 참전국 22개국. 하지만 그 숫자 뒤에는 돌아오지 못한 사람들, 기다림으로 평생을 보낸 가족들, 그리고 다시는 예전의 일상으로 돌아가지 못한 수많은 삶이 있었습니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;누군가에게 6.25전쟁은 교과서 속 사건일 수 있지만, 누군가에게는 아버지의 이름이고, 형제의 마지막 편지이며, 아직도 마음속에서 끝나지 않은 하루입니다. 전쟁은 지도 위의 선으로만 남지 않았습니다. 그것은 한 사람의 청춘을 멈추게 했고, 한 가족의 식탁에 오래도록 빈자리를 남겼으며, 한 세대의 기억 속에 깊은 침묵을 남겼습니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;그렇기에 우리는 그 희생을 단순한 역사로만 기록해서는 안 됩니다. 참전용사들의 헌신은 오늘의 대한민국이 어디에서 출발했는지 알려주는 가장 무거운 증언입니다. 그분들이 지켜낸 자유는 오늘 우리가 편안히 누리는 일상의 바탕이 되었고, 그분들이 견뎌낸 고통은 이 나라가 다시 일어설 수 있었던 힘이 되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전쟁은 끝난 것이 아니라 멈춰 서 있을 뿐입니다&lt;/h2&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;우리는 종종 6.25전쟁을 오래전에 끝난 전쟁처럼 말합니다. 하지만 정확히 말하면 한반도는 종전이 아니라 정전의 상태에 놓여 있습니다. 총성이 멈췄다고 해서 모든 상처가 사라진 것은 아니며, 전쟁의 기억은 아직도 이 땅의 역사와 현실 속에 남아 있습니다.&lt;/p&gt;
&lt;div class=&quot;kwar-quote-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총성은 멈추었지만,&lt;br /&gt;우리가 지켜야 할 자유와 평화의 책임은 아직 끝나지 않았습니다.&lt;/p&gt;
&lt;span&gt;6.25전쟁 76주년에 다시 새기는 다짐&lt;/span&gt;&lt;/div&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;그래서 6월 25일은 단순히 슬픈 역사를 떠올리는 날이 아닙니다. 평화가 얼마나 어렵게 지켜지는지, 자유가 얼마나 큰 대가 위에 서 있는지, 그리고 오늘의 대한민국이 얼마나 많은 이름 없는 헌신 위에 세워졌는지를 다시 바라보는 날입니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;자유 대한민국은 저절로 지켜진 나라가 아닙니다. 누군가가 물러서지 않았기에 지켜졌고, 누군가가 자신의 삶보다 나라의 내일을 먼저 생각했기에 이어질 수 있었습니다. 그 사실을 잊는 순간, 우리는 평화를 너무 가볍게 여기게 되고, 자유를 너무 당연하게 여기게 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;유엔 참전국, 함께 지켜낸 대한민국&lt;/h2&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;6.25전쟁 당시 대한민국은 혼자가 아니었습니다. 전 세계 여러 나라의 젊은이들이 낯선 땅의 자유와 생명을 지키기 위해 함께 싸웠고, 의료진은 전장의 한가운데에서 생명을 살리기 위해 헌신했습니다.&lt;/p&gt;
&lt;div class=&quot;kwar-grid&quot;&gt;
&lt;div class=&quot;kwar-card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전투지원 16개국&lt;/h3&gt;
&lt;p class=&quot;kwar-mini&quot; data-ke-size=&quot;size16&quot;&gt;병력과 장비를 지원한 국가들&lt;/p&gt;
&lt;span class=&quot;kwar-country&quot;&gt; 미국, 영국, 캐나다, 튀르키예, 호주, 필리핀, 태국, 네덜란드, 콜롬비아, 그리스, 뉴질랜드, 벨기에, 프랑스, 에티오피아, 남아프리카공화국, 룩셈부르크 &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;kwar-card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;의료지원 6개국&lt;/h3&gt;
&lt;p class=&quot;kwar-mini&quot; data-ke-size=&quot;size16&quot;&gt;의료진과 병원선, 의약품을 지원한 국가들&lt;/p&gt;
&lt;span class=&quot;kwar-country&quot;&gt; 스웨덴, 인도, 덴마크, 노르웨이, 이탈리아, 독일 &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p class=&quot;kwar-p&quot; style=&quot;margin-top: 22px !important;&quot; data-ke-size=&quot;size16&quot;&gt;그들은 자신의 나라가 아닌 먼 땅에서 대한민국의 자유를 위해 싸웠습니다. 낯선 언어와 낯선 계절, 낯선 산과 강 사이에서 그들이 지키고자 했던 것은 한 나라의 생존만이 아니었습니다. 그것은 자유를 향한 믿음이었고, 침략 앞에서 물러서지 않겠다는 인류 공동의 의지였습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참전용사의 헌신을 기억하는 우리의 의지&lt;/h2&gt;
&lt;div class=&quot;kwar-vow&quot;&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;기억은 단순히 과거를 바라보는 일이 아닙니다. 참전용사들의 헌신을 기억한다는 것은 오늘의 우리가 어떤 나라를 지켜야 하는지 스스로에게 묻는 일입니다. 그분들이 지켜낸 대한민국이 자유롭고, 정의롭고, 서로의 삶을 존중하는 나라로 계속 이어질 수 있도록 마음을 다잡는 일입니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;우리는 전쟁을 직접 겪지 않은 세대일 수 있습니다. 그러나 그 전쟁의 결과 위에서 살아가고 있는 세대입니다. 자유롭게 배우고, 일하고, 말하고, 선택할 수 있는 우리의 오늘은 참전용사들이 포기하지 않았던 어제와 연결되어 있습니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;그렇기에 우리의 의지는 분명해야 합니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참전용사의 희생을 잊지 않겠습니다.&lt;/b&gt; &lt;b&gt;자유 대한민국의 가치를 가볍게 여기지 않겠습니다.&lt;/b&gt; &lt;b&gt;평화를 바라되, 그 평화를 지킬 책임 또한 외면하지 않겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;div class=&quot;kwar-vow-grid&quot;&gt;
&lt;div class=&quot;kwar-vow-item&quot;&gt;&lt;b&gt;기억&lt;/b&gt; &lt;span&gt;그날의 희생을 잊지 않고 다음 세대에게 전하겠습니다.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;kwar-vow-item&quot;&gt;&lt;b&gt;감사&lt;/b&gt; &lt;span&gt;오늘의 자유가 누군가의 헌신 위에 있음을 기억하겠습니다.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;kwar-vow-item&quot;&gt;&lt;b&gt;의지&lt;/b&gt; &lt;span&gt;자유 대한민국을 지키는 마음을 일상 속에서 이어가겠습니다.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자유 대한민국을 지키기 위해 우리가 해야 할 일&lt;/h2&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;자유는 한 번 얻었다고 영원히 보장되는 것이 아닙니다. 자유는 기억하는 사람들에 의해 지켜지고, 책임지는 사람들에 의해 이어집니다. 참전용사들이 목숨으로 지켜낸 대한민국이 오늘 우리에게 남긴 과제는 분명합니다. 이 나라가 다시는 전쟁의 비극으로 무너지지 않도록, 자유와 평화의 가치를 지켜내는 성숙한 시민으로 살아가는 것입니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;그것은 거창한 말에서만 시작되지 않습니다. 나라를 위해 희생한 분들을 존중하는 마음, 역사적 사실을 바르게 기억하려는 태도, 자유와 안보를 남의 일처럼 여기지 않는 책임감, 그리고 다음 세대가 대한민국의 오늘을 당연하게만 여기지 않도록 알려주는 일에서 시작됩니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;우리는 평화를 원합니다. 그러나 평화는 잊음 위에 세워질 수 없습니다. 평화는 기억 위에 세워져야 하고, 감사 위에 자라야 하며, 자유를 지키려는 의지 위에서 오래 지속될 수 있습니다. 참전용사들의 헌신을 기억하는 일은 그래서 과거를 향한 예의이자, 미래를 향한 책임입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-section&quot;&gt;
&lt;div class=&quot;kwar-card dark&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2026년 6.25전쟁 76주년에 남기는 마음&lt;/h3&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;76년이라는 시간은 짧지 않습니다. 그러나 누군가의 희생을 잊기에는 결코 충분히 긴 시간도 아닙니다. 전쟁을 겪은 세대는 점점 우리 곁에서 멀어지고 있지만, 그들이 남긴 자유의 의미까지 함께 멀어져서는 안 됩니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;참전용사들이 지켜낸 대한민국은 폐허 위에서 다시 일어섰고, 자유의 이름으로 성장했으며, 수많은 사람들의 땀과 노력으로 오늘에 이르렀습니다. 이제 그 나라를 지키는 일은 남겨진 우리의 몫입니다. 그분들이 지켜낸 자유를 더 깊이 이해하고, 더 책임 있게 누리며, 더 단단하게 다음 세대에게 물려주는 것이 우리가 해야 할 보훈입니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;오늘 우리가 조용히 고개 숙이는 이유는 단지 슬픔 때문만은 아닙니다. 감사하기 때문입니다. 그리고 다시 다짐하기 때문입니다.&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;kwar-p&quot; data-ke-size=&quot;size16&quot;&gt;자유 대한민국을 지켜낸 헌신을 잊지 않고, 그 헌신이 부끄럽지 않은 나라로 계속 이어가겠다고 말입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;kwar-ending&quot;&gt;&lt;b&gt;당신의 헌신 위에 오늘의 대한민국이 서 있습니다.&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 다짐하겠습니다. 참전용사들이 지켜낸 자유 대한민국을 소중히 여기고, 이 땅의 평화와 자유를 다음 세대에게 온전히 전할 수 있도록 책임 있는 마음으로 살아가겠습니다.&lt;/p&gt;
&lt;p class=&quot;kwar-last-line&quot; data-ke-size=&quot;size16&quot;&gt;잊지 않겠습니다.&lt;br /&gt;그리고 자유 대한민국을 끝까지 지켜가겠습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>6.25전쟁</category>
      <category>대한민국</category>
      <category>보훈</category>
      <category>우방국</category>
      <category>유엔참전국</category>
      <category>자유대한</category>
      <category>정전협정</category>
      <category>참전용사</category>
      <category>한국전쟁</category>
      <category>호국보훈의달</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/591</guid>
      <comments>https://odinbox.tistory.com/591#entry591comment</comments>
      <pubDate>Thu, 25 Jun 2026 07:58:31 +0900</pubDate>
    </item>
    <item>
      <title>2026 경복궁 야간관람 후기, 퇴근 후 만난 근정전&amp;middot;경회루 야경과 광화문광장 산책</title>
      <link>https://odinbox.tistory.com/590</link>
      <description>&lt;div id=&quot;gbk_post&quot;&gt;
&lt;style&gt;
    #gbk_post {
      max-width: 900px;
      margin: 0 auto;
      color: #2f261f;
      font-family: &quot;Noto Serif KR&quot;, &quot;Nanum Myeongjo&quot;, &quot;Batang&quot;, serif;
      line-height: 1.86;
      letter-spacing: -0.01em;
      word-break: keep-all;
    }
    #gbk_post * {
      box-sizing: border-box;
    }
    #gbk_post .gbk_wrap {
      background: #fbf7f0;
      border: 1px solid #d8c8b2;
      box-shadow: 0 10px 30px rgba(44, 32, 24, 0.08);
    }
    #gbk_post .gbk_header {
      padding: 36px 28px 30px;
      background:
        linear-gradient(180deg, rgba(246, 239, 227, 0.96) 0%, rgba(251, 247, 240, 0.98) 100%),
        radial-gradient(circle at top left, rgba(143, 109, 72, 0.16), transparent 32%);
      border-bottom: 1px solid #d8c8b2;
    }
    #gbk_post .gbk_kicker {
      display: inline-block;
      margin-bottom: 12px;
      padding: 5px 11px;
      border: 1px solid #b79b77;
      color: #6b4f33;
      font-size: 12px;
      background: #fffaf2;
    }
    #gbk_post h1 {
      margin: 0 0 12px;
      font-size: 34px;
      line-height: 1.42;
      color: #241911;
      letter-spacing: -0.035em;
    }
    #gbk_post .gbk_meta {
      margin: 0;
      font-size: 14px;
      color: #6a5848;
    }
    #gbk_post .gbk_thumbnail_image {
      margin: 24px 0 10px;
      text-align: center;
    }
    #gbk_post .gbk_body {
      padding: 30px 28px 36px;
    }
    #gbk_post h2 {
      margin: 44px 0 16px;
      padding-bottom: 9px;
      border-bottom: 1px solid #d8c8b2;
      font-size: 26px;
      color: #2c1f16;
      letter-spacing: -0.025em;
    }
    #gbk_post h3 {
      margin: 32px 0 13px;
      font-size: 21px;
      color: #3f2b1b;
      letter-spacing: -0.02em;
    }
    #gbk_post h4 {
      margin: 25px 0 10px;
      font-size: 18px;
      color: #5a4028;
    }
    #gbk_post p {
      margin: 0 0 16px;
    }
    #gbk_post a {
      color: #765636;
      text-decoration: none;
      border-bottom: 1px solid #ccb395;
    }
    #gbk_post a:hover {
      background: #f5ebdc;
    }
    #gbk_post .gbk_lead,
    #gbk_post .gbk_quote {
      padding: 18px 20px;
      background: #fffdf9;
      border-left: 4px solid #8f6d48;
      color: #3a2c21;
    }
    #gbk_post .gbk_notice,
    #gbk_post .gbk_note,
    #gbk_post .gbk_tipbox,
    #gbk_post .gbk_summary,
    #gbk_post .gbk_route {
      margin: 19px 0;
      padding: 17px 19px;
      border: 1px solid #d8c8b2;
      background: #fffaf3;
    }
    #gbk_post .gbk_notice {
      background: #f7efe1;
      border-color: #c9ad83;
    }
    #gbk_post .gbk_notice strong,
    #gbk_post .gbk_note strong,
    #gbk_post .gbk_tipbox strong,
    #gbk_post .gbk_summary strong,
    #gbk_post .gbk_route strong {
      display: block;
      margin-bottom: 8px;
      color: #50361f;
    }
    #gbk_post .gbk_notice p {
      margin: 0;
    }
    #gbk_post .gbk_summary ul,
    #gbk_post .gbk_tipbox ul,
    #gbk_post .gbk_route ol {
      margin: 0;
      padding-left: 20px;
    }
    #gbk_post .gbk_summary li,
    #gbk_post .gbk_tipbox li,
    #gbk_post .gbk_route li {
      margin: 7px 0;
    }
    #gbk_post .gbk_table_wrap {
      overflow-x: auto;
      margin: 18px 0 24px;
      border: 1px solid #d8c8b2;
      background: #fffdf9;
    }
    #gbk_post table {
      width: 100%;
      min-width: 760px;
      border-collapse: collapse;
      font-size: 14px;
    }
    #gbk_post th,
    #gbk_post td {
      padding: 12px 10px;
      border: 1px solid #e2d4c1;
      vertical-align: top;
      text-align: left;
    }
    #gbk_post th {
      background: #f4ebde;
      color: #3d2b1d;
      font-weight: 700;
    }
    #gbk_post .gbk_gallery_title {
      margin: 36px 0 18px;
      padding: 13px 15px;
      background: #efe3d1;
      border: 1px solid #d8c8b2;
      color: #3d2b1d;
      font-weight: 700;
    }
    #gbk_post .gbk_photo_image {
      margin: 26px 0 12px;
      text-align: center;
    }
    #gbk_post .gbk_photo_image img,
    #gbk_post .gbk_thumbnail_image img {
      max-width: 100%;
      height: auto;
    }
    #gbk_post .gbk_caption {
      margin: 0 0 30px;
      padding: 12px 14px;
      font-size: 14px;
      line-height: 1.78;
      color: #5e4d3f;
      background: #f8f1e7;
      border-left: 3px solid #8f6d48;
    }
    #gbk_post .gbk_quote {
      margin: 26px 0;
      background: #f8f1e7;
      font-size: 17px;
    }
    #gbk_post details {
      margin: 26px 0 8px;
      border: 1px solid #d8c8b2;
      background: #fffdf9;
    }
    #gbk_post summary {
      cursor: pointer;
      padding: 14px 16px;
      font-weight: 700;
      color: #3a281a;
      background: #f7efe1;
    }
    #gbk_post .gbk_source_list {
      padding: 10px 16px 16px;
    }
    #gbk_post .gbk_source_list ul {
      margin: 0;
      padding-left: 20px;
    }
    #gbk_post .gbk_source_list li {
      margin: 7px 0;
      word-break: break-all;
    }
    #gbk_post .gbk_tags {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 12px;
    }
    #gbk_post .gbk_tags span {
      display: inline-block;
      padding: 6px 10px;
      border: 1px solid #ccb395;
      background: #fffaf3;
      color: #6d563d;
      font-size: 13px;
    }
    @media (max-width: 720px) {
      #gbk_post .gbk_header,
      #gbk_post .gbk_body {
        padding: 22px 16px 28px;
      }
      #gbk_post h1 {
        font-size: 28px;
      }
      #gbk_post h2 {
        font-size: 22px;
      }
      #gbk_post h3 {
        font-size: 19px;
      }
      #gbk_post table {
        min-width: 680px;
      }
      #gbk_post .gbk_caption {
        margin-bottom: 24px;
      }
    }
  &lt;/style&gt;
&lt;div class=&quot;gbk_wrap&quot;&gt;
&lt;div class=&quot;gbk_header&quot;&gt;
&lt;div class=&quot;gbk_kicker&quot;&gt;2026년 상반기 경복궁 야간관람 후기&lt;/div&gt;
&lt;p class=&quot;gbk_meta&quot; data-ke-size=&quot;size16&quot;&gt;방문일: 2026.06.10.(수) / 상반기 야간관람 종료: 2026.06.14.(일) / 핵심 정보: 예매, 주차, 무료입장, 관람동선, 사진 포인트, 하반기 방문 준비까지 정리했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gbk_body&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (4).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvGxu8/dJMcajimbPg/zjj7DWTr8iW9TzZSYokm1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvGxu8/dJMcajimbPg/zjj7DWTr8iW9TzZSYokm1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvGxu8/dJMcajimbPg/zjj7DWTr8iW9TzZSYokm1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvGxu8%2FdJMcajimbPg%2Fzjj7DWTr8iW9TzZSYokm1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (4).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;2026년 상반기 경복궁 야간관람 후기 대표 이미지입니다. 퇴근 후 마주한 근정전과 경회루의 밤, 그리고 광화문광장 산책까지 이어진 하루를 담았습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;서론&lt;/h2&gt;
&lt;p class=&quot;gbk_lead&quot; data-ke-size=&quot;size16&quot;&gt;2026년 6월 10일 수요일, 퇴근을 마치고 바로 경복궁 야간관람을 다녀왔습니다. 2026년 상반기 야간관람 티켓팅에 운 좋게 성공했고, 평일 저녁에 서울 도심으로 직접 운전해서 이동했습니다. 처음 서울 운전을 하는 일정이라 출발 전부터 주차가 가장 걱정되었지만, 오후 7시쯤 경복궁 부설주차장에 도착했을 때 다행히 자리가 남아 있어 마음을 놓을 수 있었습니다.&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;현재 기준으로 2026년 상반기 경복궁 야간관람은 &lt;b&gt;2026년 6월 14일&lt;/b&gt;을 끝으로 종료되었습니다. 따라서 지금 이 글을 보시는 분들은 상반기 방문 후기로 참고하시고, 앞으로 방문을 계획하신다면 &lt;b&gt;하반기 야간관람 일정 공지&lt;/b&gt;와 예매 오픈 일정을 반드시 확인하시는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 제가 실제로 다녀온 방문 동선을 기준으로, 경복궁 야간관람 예매 정보, 한복 무료입장, 외국인 현장예매, 주차장 이용 팁, 근정전과 경회루 관람 포인트, 광화문광장과 감사의 정원 산책까지 한 번에 정리했습니다.&lt;/p&gt;
&lt;p 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;div class=&quot;gbk_notice&quot;&gt;&lt;b&gt;현재 기준 안내입니다.&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 상반기 경복궁 야간관람은 공식 안내 기준으로 2026.05.13.(수)부터 2026.06.14.(일)까지 운영되었고, 매주 월요일과 화요일은 야간관람이 없었습니다. 지금은 상반기 일정이 종료된 상태이므로, 다음 방문을 준비하신다면 경복궁 공식 누리집의 하반기 야간관람 공지를 확인하시는 것이 가장 정확합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gbk_summary&quot;&gt;&lt;b&gt;방문 전 핵심 요약입니다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2026년 상반기 경복궁 야간관람은 2026.05.13.~2026.06.14. 기간에 운영되었고, 현재는 종료되었습니다.&lt;/li&gt;
&lt;li&gt;관람 시간은 19:00~21:30이며, 입장 마감은 20:30이었습니다.&lt;/li&gt;
&lt;li&gt;관람 요금은 일반 기준 3,000원이었고, 한복 착용자는 무료입장이 가능했습니다.&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;/div&gt;
&lt;div class=&quot;gbk_tipbox&quot;&gt;&lt;b&gt;이 글에서 확인할 수 있는 정보입니다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2026년 상반기 경복궁 야간관람 운영기간, 관람시간, 입장 마감 시간, 예매 방식과 하반기 방문 준비 시 확인할 점입니다.&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;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주차와 입장&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 일정에서 가장 걱정했던 부분은 주차였습니다. 서울 도심 운전이 익숙하지 않은 상태에서 퇴근 후 바로 움직이는 일정이었기 때문에, 출발 전부터 경복궁 부설주차장과 주변 대체 주차장을 함께 확인해 두었습니다. 실제로는 평일 오후 7시쯤 도착했는데, 다행히 경복궁 부설주차장에 자리가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로는 자차로 방문하신다면 &lt;b&gt;경복궁 부설주차장&lt;/b&gt;을 먼저 목적지로 잡고, 만차일 경우 &lt;b&gt;국립현대미술관 서울관 주차장&lt;/b&gt;이나 &lt;b&gt;경복궁역&amp;middot;서촌 권역 주차장&lt;/b&gt;을 대안으로 보시는 방식이 가장 현실적이라고 느꼈습니다. 주차만 해결되면 경복궁 입장 동선은 비교적 단순해서 관람에 집중하기 좋았습니다.&lt;/p&gt;
&lt;div class=&quot;gbk_table_wrap&quot;&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;개인적으로 느낀 점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1순위&lt;/td&gt;
&lt;td&gt;경복궁 부설주차장&lt;/td&gt;
&lt;td&gt;경복궁과 가장 가까워 관람 동선이 편합니다. 평일 저녁에는 운이 좋으면 주차가 가능하지만, 주말이나 인기 날짜에는 만차 가능성을 생각해야 합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2순위&lt;/td&gt;
&lt;td&gt;국립현대미술관 서울관 주차장&lt;/td&gt;
&lt;td&gt;경복궁 동쪽과 삼청동 방향으로 접근하기 좋아 대체 주차장으로 생각해볼 만합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3순위&lt;/td&gt;
&lt;td&gt;경복궁역&amp;middot;서촌&amp;middot;광화문 주변 주차장&lt;/td&gt;
&lt;td&gt;도보 이동이 조금 늘어날 수 있지만, 경복궁 관람 후 광화문광장까지 함께 보실 분께는 대안이 될 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;gbk_gallery_title&quot;&gt;주차장과 입장 전후에 남긴 사진입니다.&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s8VK7/dJMcadI7QWd/LRgarbkQf5hcniKbv4VEOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s8VK7/dJMcadI7QWd/LRgarbkQf5hcniKbv4VEOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s8VK7/dJMcadI7QWd/LRgarbkQf5hcniKbv4VEOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs8VK7%2FdJMcadI7QWd%2FLRgarbkQf5hcniKbv4VEOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;경복궁 부설주차장 모습입니다. 평일 오후 7시쯤 도착했는데, 생각보다 자리가 있어 가장 걱정했던 주차 문제를 무사히 해결할 수 있었습니다.&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;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FfCyo/dJMcaa6QiAE/aSO5B5U6FZxkRzpkA3bEkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FfCyo/dJMcaa6QiAE/aSO5B5U6FZxkRzpkA3bEkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FfCyo/dJMcaa6QiAE/aSO5B5U6FZxkRzpkA3bEkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFfCyo%2FdJMcaa6QiAE%2FaSO5B5U6FZxkRzpkA3bEkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFlGl5/dJMcaaZ0Zxv/pqRaZkT1yaAHck2X8YcvKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFlGl5/dJMcaaZ0Zxv/pqRaZkT1yaAHck2X8YcvKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFlGl5/dJMcaaZ0Zxv/pqRaZkT1yaAHck2X8YcvKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFlGl5%2FdJMcaaZ0Zxv%2FpqRaZkT1yaAHck2X8YcvKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/soH0W/dJMcahrmkCp/dJjhsY81KcVc02Xm8aDP61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/soH0W/dJMcahrmkCp/dJjhsY81KcVc02Xm8aDP61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/soH0W/dJMcahrmkCp/dJjhsY81KcVc02Xm8aDP61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsoH0W%2FdJMcahrmkCp%2FdJjhsY81KcVc02Xm8aDP61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uzuOO/dJMcadPU6q2/K2VKkBO0jVl6fvLoieUNk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uzuOO/dJMcadPU6q2/K2VKkBO0jVl6fvLoieUNk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uzuOO/dJMcadPU6q2/K2VKkBO0jVl6fvLoieUNk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuzuOO%2FdJMcadPU6q2%2FK2VKkBO0jVl6fvLoieUNk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lpEN4/dJMcahx51oO/3bXycaJk0mOsVdepa6pggK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lpEN4/dJMcahx51oO/3bXycaJk0mOsVdepa6pggK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lpEN4/dJMcahx51oO/3bXycaJk0mOsVdepa6pggK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlpEN4%2FdJMcahx51oO%2F3bXycaJk0mOsVdepa6pggK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3I9pu/dJMcaalnG7A/o3oklPJlDAgjiRAnUqKVl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3I9pu/dJMcaalnG7A/o3oklPJlDAgjiRAnUqKVl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3I9pu/dJMcaalnG7A/o3oklPJlDAgjiRAnUqKVl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3I9pu%2FdJMcaalnG7A%2Fo3oklPJlDAgjiRAnUqKVl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIXeEj/dJMcaf1ism7/mVZVQCcLa70xn8I1kmdUq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIXeEj/dJMcaf1ism7/mVZVQCcLa70xn8I1kmdUq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIXeEj/dJMcaf1ism7/mVZVQCcLa70xn8I1kmdUq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIXeEj%2FdJMcaf1ism7%2FmVZVQCcLa70xn8I1kmdUq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WldNx/dJMcahrmkvJ/ClqrsDLpkPchAQjw4wuxQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WldNx/dJMcahrmkvJ/ClqrsDLpkPchAQjw4wuxQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WldNx/dJMcahrmkvJ/ClqrsDLpkPchAQjw4wuxQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWldNx%2FdJMcahrmkvJ%2FClqrsDLpkPchAQjw4wuxQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;경복궁 안내도입니다. 야간에는 동선이 제한적으로 운영되기 때문에, 입장 전 안내도를 한 번 보고 움직이면 관람 흐름을 잡기 좋습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;지금 보시는 분들을 위한 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 2026년 상반기 야간관람을 직접 다녀온 후기입니다. 상반기 일정은 이미 종료되었기 때문에, 지금 경복궁 야간관람을 준비하시는 분들은 이 후기를 &lt;b&gt;방문 동선, 주차 전략, 사진 포인트, 관람 분위기&lt;/b&gt;를 참고하는 글로 보시면 좋습니다. 실제 예매 일정과 관람 기간은 하반기 공지가 올라온 뒤 다시 확인하셔야 합니다.&lt;/p&gt;
&lt;div class=&quot;gbk_tipbox&quot;&gt;&lt;b&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;/li&gt;
&lt;li&gt;예매처가 열리면 예매 시작 시간 전에 로그인과 결제수단을 미리 준비합니다.&lt;/li&gt;
&lt;li&gt;방문 날짜를 고를 때는 월&amp;middot;화요일 휴무 여부와 입장 마감 시간을 꼭 확인합니다.&lt;/li&gt;
&lt;li&gt;자차 방문 예정이라면 경복궁 부설주차장, 국립현대미술관 서울관, 경복궁역 주변 주차장을 미리 저장해 둡니다.&lt;/li&gt;
&lt;li&gt;사진을 중요하게 생각하신다면 해질녘 입장 후 근정전, 완전한 야간 시간대의 경회루를 중심으로 동선을 잡는 것이 좋습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;경복궁 야간관람 기본 정보&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 상반기 경복궁 야간관람은 사전예매 경쟁이 있는 행사였고, 현재는 2026년 6월 14일을 끝으로 종료된 일정입니다. 저는 운 좋게 티켓팅에 성공했고, 퇴근 후 바로 이동해서 관람할 수 있었습니다. 현장에서는 한복을 입고 입장하는 분들도 보였는데, 경복궁 야간관람은 한복 착용자 무료입장이 가능하다는 점이 큰 장점입니다. 다만 저는 한복을 입고 갈 자신이 없어서 일반 예매권으로 입장했습니다.&lt;/p&gt;
&lt;div class=&quot;gbk_table_wrap&quot;&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;참고사항&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;방문일&lt;/td&gt;
&lt;td&gt;2026년 6월 10일 수요일&lt;/td&gt;
&lt;td&gt;평일 퇴근 후 방문이었고, 오후 7시 전후 도착 기준으로 관람 시간이 적당했습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;관람 시간&lt;/td&gt;
&lt;td&gt;19:00~21:30&lt;/td&gt;
&lt;td&gt;입장 마감은 20:30이므로 늦게 도착하면 관람 시간이 짧아질 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;요금&lt;/td&gt;
&lt;td&gt;일반 관람권 3,000원&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;/div&gt;
&lt;div class=&quot;gbk_note&quot;&gt;&lt;b&gt;공식 정보 확인 안내입니다.&lt;/b&gt;&lt;br /&gt;야간관람 일정, 예매처, 인원 제한, 무료입장 대상, 입장 마감 시간은 시즌마다 달라질 수 있습니다. 경복궁 야간관람을 다시 계획하신다면 궁능유적본부 경복궁 공식 공지와 예매처 공지를 먼저 확인하시는 것이 가장 안전합니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;입장 후 초입에서 느낀 야간 경복궁의 분위기&lt;/h2&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;div class=&quot;gbk_gallery_title&quot;&gt;경복궁 초입과 야간 분위기입니다.&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3Cgwn/dJMcabR7OFj/P3R9krozyDXm4kx7Z8WWKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3Cgwn/dJMcabR7OFj/P3R9krozyDXm4kx7Z8WWKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3Cgwn/dJMcabR7OFj/P3R9krozyDXm4kx7Z8WWKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3Cgwn%2FdJMcabR7OFj%2FP3R9krozyDXm4kx7Z8WWKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vudUf/dJMcaicKydv/m5ZXz8OSIfMF9b2OxdmW61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vudUf/dJMcaicKydv/m5ZXz8OSIfMF9b2OxdmW61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vudUf/dJMcaicKydv/m5ZXz8OSIfMF9b2OxdmW61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvudUf%2FdJMcaicKydv%2Fm5ZXz8OSIfMF9b2OxdmW61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E5xJR/dJMcaicKxzh/HQTjpFZYzQ6bOfeNdddRAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E5xJR/dJMcaicKxzh/HQTjpFZYzQ6bOfeNdddRAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E5xJR/dJMcaicKxzh/HQTjpFZYzQ6bOfeNdddRAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE5xJR%2FdJMcaicKxzh%2FHQTjpFZYzQ6bOfeNdddRAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu676P/dJMcaicKxzj/K9NOYUVWyp5lvvhGjk3s21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu676P/dJMcaicKxzj/K9NOYUVWyp5lvvhGjk3s21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu676P/dJMcaicKxzj/K9NOYUVWyp5lvvhGjk3s21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu676P%2FdJMcaicKxzj%2FK9NOYUVWyp5lvvhGjk3s21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZcFva/dJMb99UkZ9o/QfRt2katuUkUNWapNRSAc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZcFva/dJMb99UkZ9o/QfRt2katuUkUNWapNRSAc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZcFva/dJMb99UkZ9o/QfRt2katuUkUNWapNRSAc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZcFva%2FdJMb99UkZ9o%2FQfRt2katuUkUNWapNRSAc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzWQ3g/dJMcacXP37k/XwdcHr0bLKUpsLu4QXACVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzWQ3g/dJMcacXP37k/XwdcHr0bLKUpsLu4QXACVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzWQ3g/dJMcacXP37k/XwdcHr0bLKUpsLu4QXACVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzWQ3g%2FdJMcacXP37k%2FXwdcHr0bLKUpsLu4QXACVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1552&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UHyPe/dJMcajimaJj/AXk3lgCeYrthf8EWGy14Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UHyPe/dJMcajimaJj/AXk3lgCeYrthf8EWGy14Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UHyPe/dJMcajimaJj/AXk3lgCeYrthf8EWGy14Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUHyPe%2FdJMcajimaJj%2FAXk3lgCeYrthf8EWGy14Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1552&quot; height=&quot;872&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1290&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMLWWn/dJMcahdNXFS/Er1Ac02LKDjxXliQBZpRe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMLWWn/dJMcahdNXFS/Er1Ac02LKDjxXliQBZpRe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMLWWn/dJMcahdNXFS/Er1Ac02LKDjxXliQBZpRe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMLWWn%2FdJMcahdNXFS%2FEr1Ac02LKDjxXliQBZpRe0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1290&quot; height=&quot;725&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1290&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;사진이 조금 흔들렸지만, 오히려 밤의 경복궁이 가진 아련한 분위기가 담겨 있어 함께 남겨두었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;근정전, 조선 법궁의 중심을 밤에 만났습니다&lt;/h2&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;div class=&quot;gbk_gallery_title&quot;&gt;근정전의 해질녘과 야간 모습입니다.&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byoQTc/dJMb99NwM40/QUjYCvfMlCaQvlmn1Fbqnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byoQTc/dJMb99NwM40/QUjYCvfMlCaQvlmn1Fbqnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byoQTc/dJMb99NwM40/QUjYCvfMlCaQvlmn1Fbqnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyoQTc%2FdJMb99NwM40%2FQUjYCvfMlCaQvlmn1Fbqnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1427&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfuJyb/dJMcabdu67d/lGr3O5cpwuP9UkLyANWC30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfuJyb/dJMcabdu67d/lGr3O5cpwuP9UkLyANWC30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfuJyb/dJMcabdu67d/lGr3O5cpwuP9UkLyANWC30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfuJyb%2FdJMcabdu67d%2FlGr3O5cpwuP9UkLyANWC30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1427&quot; height=&quot;803&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1427&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JA06w/dJMcafNRLCt/rikqOidKflRjzD7b0g3P11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JA06w/dJMcafNRLCt/rikqOidKflRjzD7b0g3P11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JA06w/dJMcafNRLCt/rikqOidKflRjzD7b0g3P11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJA06w%2FdJMcafNRLCt%2FrikqOidKflRjzD7b0g3P11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1484&quot; data-origin-height=&quot;835&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Ih0q/dJMcaff0FQ8/Le2lwWMEMzguaeNtcIGcF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Ih0q/dJMcaff0FQ8/Le2lwWMEMzguaeNtcIGcF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Ih0q/dJMcaff0FQ8/Le2lwWMEMzguaeNtcIGcF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Ih0q%2FdJMcaff0FQ8%2FLe2lwWMEMzguaeNtcIGcF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1484&quot; height=&quot;835&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1484&quot; data-origin-height=&quot;835&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;근정전 내부를 다른 각도에서 담은 사진입니다. 어좌와 병풍을 다시 보니, 근정전이 단순한 전각이 아니라 국가 의례의 중심 공간이었다는 점이 실감났습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사정전, 흠경각, 그리고 궁궐 안쪽의 세부 풍경&lt;/h2&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;middot;의례&amp;middot;과학&amp;middot;생활이 함께 담긴 복합적인 공간이라는 점을 다시 느낄 수 있었습니다.&lt;/p&gt;
&lt;div class=&quot;gbk_gallery_title&quot;&gt;사정전, 흠경각, 담장과 세부 풍경입니다.&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pI6kz/dJMcaasdQwY/aud7gRLK9D7gag38abGhyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pI6kz/dJMcaasdQwY/aud7gRLK9D7gag38abGhyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pI6kz/dJMcaasdQwY/aud7gRLK9D7gag38abGhyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpI6kz%2FdJMcaasdQwY%2Faud7gRLK9D7gag38abGhyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1296&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/msaBc/dJMcabdu67h/TRXk9K1imqBAgY6PaKN2y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/msaBc/dJMcabdu67h/TRXk9K1imqBAgY6PaKN2y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/msaBc/dJMcabdu67h/TRXk9K1imqBAgY6PaKN2y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmsaBc%2FdJMcabdu67h%2FTRXk9K1imqBAgY6PaKN2y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1296&quot; height=&quot;728&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beZAIs/dJMcaaeGBys/xzRQI0NptiQptpTcw5kvvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beZAIs/dJMcaaeGBys/xzRQI0NptiQptpTcw5kvvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beZAIs/dJMcaaeGBys/xzRQI0NptiQptpTcw5kvvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeZAIs%2FdJMcaaeGBys%2FxzRQI0NptiQptpTcw5kvvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dztKW8/dJMcaicKxGi/39uXeU1dwfJd0pAXtwM6f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dztKW8/dJMcaicKxGi/39uXeU1dwfJd0pAXtwM6f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dztKW8/dJMcaicKxGi/39uXeU1dwfJd0pAXtwM6f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdztKW8%2FdJMcaicKxGi%2F39uXeU1dwfJd0pAXtwM6f1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;경복궁 담벼락을 지나가다 분위기가 좋아 남긴 사진입니다. 전각뿐 아니라 담장과 길의 선에서도 궁궐 특유의 고풍스러움이 느껴졌습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;경회루, 어두워지기를 기다릴 가치가 있는 장면&lt;/h2&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;div class=&quot;gbk_gallery_title&quot;&gt;경회루의 해질녘과 야간 모습입니다.&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckpgmw/dJMcajvT4kG/6OptruKitFOvoegz4lfkGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckpgmw/dJMcajvT4kG/6OptruKitFOvoegz4lfkGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckpgmw/dJMcajvT4kG/6OptruKitFOvoegz4lfkGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fckpgmw%2FdJMcajvT4kG%2F6OptruKitFOvoegz4lfkGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;780&quot; data-origin-height=&quot;1387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PDfRF/dJMcafG4HKP/IrM7IL6qkRNKoduGPpCVWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PDfRF/dJMcafG4HKP/IrM7IL6qkRNKoduGPpCVWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PDfRF/dJMcafG4HKP/IrM7IL6qkRNKoduGPpCVWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPDfRF%2FdJMcafG4HKP%2FIrM7IL6qkRNKoduGPpCVWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;1387&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;1387&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1209&quot; data-origin-height=&quot;680&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rHU2O/dJMcafG4HKY/HiTlI1NgXPo7yhVsxKPjXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rHU2O/dJMcafG4HKY/HiTlI1NgXPo7yhVsxKPjXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rHU2O/dJMcafG4HKY/HiTlI1NgXPo7yhVsxKPjXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrHU2O%2FdJMcafG4HKY%2FHiTlI1NgXPo7yhVsxKPjXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1209&quot; height=&quot;680&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;680&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvbr76/dJMcacp2MAS/Ir35slYzswexhLmsx9GPd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvbr76/dJMcacp2MAS/Ir35slYzswexhLmsx9GPd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvbr76/dJMcacp2MAS/Ir35slYzswexhLmsx9GPd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvbr76%2FdJMcacp2MAS%2FIr35slYzswexhLmsx9GPd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enmMs4/dJMcaaTgttY/uWH0yss4A00GkXJicI52pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enmMs4/dJMcaaTgttY/uWH0yss4A00GkXJicI52pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enmMs4/dJMcaaTgttY/uWH0yss4A00GkXJicI52pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FenmMs4%2FdJMcaaTgttY%2FuWH0yss4A00GkXJicI52pk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;경회루 야간 모습을 한 번 더 담았습니다. 너무 아름다워 여러 장을 찍게 되었고, 연못과 조명이 함께 만드는 분위기가 특히 좋았습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;광화문광장, 세종대왕 동상과 이순신 장군 동상&lt;/h2&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광화문대로의 불빛과 지하철 출구, 주변 건물의 광고 화면까지 더해져 현대 서울의 야간 분위기도 함께 느낄 수 있었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;감사의 정원, 자유와 평화를 기억하는 빛&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광화문광장에서 특히 인상 깊었던 곳은 감사의 정원이었습니다. 감사의 정원은 6&amp;middot;25전쟁 당시 대한민국의 자유와 평화를 위해 함께해 준 참전국과 참전용사를 기억하는 공간입니다. 저는 이런 취지의 조형물과 기념 공간이 더 많이 만들어져야 한다고 생각하는 입장이라, 실제로 보았을 때 의미 있게 다가왔습니다.&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;div class=&quot;gbk_gallery_title&quot;&gt;광화문광장, 감사의 정원, 주변 야간 풍경입니다.&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Yznao/dJMcafUBl82/qeBY4K3kLp0Kb1nWYtjAG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Yznao/dJMcafUBl82/qeBY4K3kLp0Kb1nWYtjAG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Yznao/dJMcafUBl82/qeBY4K3kLp0Kb1nWYtjAG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYznao%2FdJMcafUBl82%2FqeBY4K3kLp0Kb1nWYtjAG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;805&quot; data-origin-height=&quot;1430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyPE2o/dJMcahkBTWC/8Z3n6GzofaDkrQ40O6bfU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyPE2o/dJMcahkBTWC/8Z3n6GzofaDkrQ40O6bfU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyPE2o/dJMcahkBTWC/8Z3n6GzofaDkrQ40O6bfU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyPE2o%2FdJMcahkBTWC%2F8Z3n6GzofaDkrQ40O6bfU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;1430&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;1430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1290&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WLvDr/dJMcaaMupSB/68tcF2jP1pC9EuKGAkk0Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WLvDr/dJMcaaMupSB/68tcF2jP1pC9EuKGAkk0Sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WLvDr/dJMcaaMupSB/68tcF2jP1pC9EuKGAkk0Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWLvDr%2FdJMcaaMupSB%2F68tcF2jP1pC9EuKGAkk0Sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1290&quot; height=&quot;725&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1290&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3dWDt/dJMcafNRLQP/sJM67Tfb1kcBuxrvqvu09K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3dWDt/dJMcafNRLQP/sJM67Tfb1kcBuxrvqvu09K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3dWDt/dJMcafNRLQP/sJM67Tfb1kcBuxrvqvu09K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3dWDt%2FdJMcafNRLQP%2FsJM67Tfb1kcBuxrvqvu09K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEHzPK/dJMcaiXZeUU/GbnlYH3ntV16dKyObJwmK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEHzPK/dJMcaiXZeUU/GbnlYH3ntV16dKyObJwmK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEHzPK/dJMcaiXZeUU/GbnlYH3ntV16dKyObJwmK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEHzPK%2FdJMcaiXZeUU%2FGbnlYH3ntV16dKyObJwmK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;광화문역 3번 출구 입구입니다. 대중교통으로 방문하실 분들은 경복궁과 광화문광장을 함께 둘러보기 좋은 위치입니다.&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;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DICc0/dJMcai4KTIp/1GbeXaq8pLtcgY6LKwQDzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DICc0/dJMcai4KTIp/1GbeXaq8pLtcgY6LKwQDzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DICc0/dJMcai4KTIp/1GbeXaq8pLtcgY6LKwQDzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDICc0%2FdJMcai4KTIp%2F1GbeXaq8pLtcgY6LKwQDzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;광화문역 3번 출구 입구를 다른 각도에서 담은 사진입니다. 경복궁과 광화문광장을 대중교통으로 연결해 주는 지점이라 기억해 두면 좋습니다.&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;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bseSA0/dJMcacXP4fQ/uKwvyIj6HIxkyRwGIKkpRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bseSA0/dJMcacXP4fQ/uKwvyIj6HIxkyRwGIKkpRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bseSA0/dJMcacXP4fQ/uKwvyIj6HIxkyRwGIKkpRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbseSA0%2FdJMcacXP4fQ%2FuKwvyIj6HIxkyRwGIKkpRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EEPKc/dJMcaaTgs42/jjNtAlipYujXI0K7EjpdhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EEPKc/dJMcaaTgs42/jjNtAlipYujXI0K7EjpdhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EEPKc/dJMcaaTgs42/jjNtAlipYujXI0K7EjpdhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEEPKc%2FdJMcaaTgs42%2FjjNtAlipYujXI0K7EjpdhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;광화문광장에 조성된 감사의 정원입니다. 6&amp;middot;25전쟁 당시 자유대한민국을 위해 함께해 준 참전국과 참전용사를 기억하는 공간이라는 점에서 의미 있게 다가왔습니다.&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;1600&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5lEdP/dJMb997Sfcs/2OvOvq1aGG8K1asTdTKKs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5lEdP/dJMb997Sfcs/2OvOvq1aGG8K1asTdTKKs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5lEdP/dJMb997Sfcs/2OvOvq1aGG8K1asTdTKKs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5lEdP%2FdJMb997Sfcs%2F2OvOvq1aGG8K1asTdTKKs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;900&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0eZAI/dJMb9909EY8/m1YvjcunompK9GKStmzbf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0eZAI/dJMb9909EY8/m1YvjcunompK9GKStmzbf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0eZAI/dJMb9909EY8/m1YvjcunompK9GKStmzbf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0eZAI%2FdJMb9909EY8%2Fm1YvjcunompK9GKStmzbf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;900&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3kxs1/dJMcafmMcJe/7KoNs4IEdfbYn2bAZDzOkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3kxs1/dJMcafmMcJe/7KoNs4IEdfbYn2bAZDzOkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3kxs1/dJMcafmMcJe/7KoNs4IEdfbYn2bAZDzOkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3kxs1%2FdJMcafmMcJe%2F7KoNs4IEdfbYn2bAZDzOkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CjbjQ/dJMcag0bZXa/CHDhTwJXjBY7H04WbT4z0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CjbjQ/dJMcag0bZXa/CHDhTwJXjBY7H04WbT4z0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CjbjQ/dJMcag0bZXa/CHDhTwJXjBY7H04WbT4z0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCjbjQ%2FdJMcag0bZXa%2FCHDhTwJXjBY7H04WbT4z0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&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;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kBDVL/dJMcahSkJXP/tu6GJGz2C4nkmKmYGPYJG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kBDVL/dJMcahSkJXP/tu6GJGz2C4nkmKmYGPYJG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kBDVL/dJMcahSkJXP/tu6GJGz2C4nkmKmYGPYJG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkBDVL%2FdJMcahSkJXP%2Ftu6GJGz2C4nkmKmYGPYJG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;gbk_caption&quot; data-ke-size=&quot;size16&quot;&gt;주한미국대사관 담벼락 근처에서 바라본 풍경입니다. 성조기가 바람에 흔들리는 모습이 보여, 광화문 일대가 가진 국제적인 분위기도 함께 느껴졌습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전체 동선 정리&lt;/h2&gt;
&lt;div class=&quot;gbk_route&quot;&gt;&lt;b&gt;제가 실제로 걸었던 흐름입니다.&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;퇴근 후 차량으로 경복궁 이동&lt;/li&gt;
&lt;li&gt;경복궁 부설주차장 주차&lt;/li&gt;
&lt;li&gt;매표소 방향으로 이동 후 입장&lt;/li&gt;
&lt;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;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;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;관람 팁과 주의사항&lt;/h2&gt;
&lt;div class=&quot;gbk_tipbox&quot;&gt;&lt;b&gt;직접 다녀와서 느낀 팁입니다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자차 방문이라면 경복궁 부설주차장을 1순위로 보되, 만차에 대비해 대체 주차장을 미리 저장해 두시는 것이 좋습니다.&lt;/li&gt;
&lt;li&gt;평일 저녁 7시쯤에는 운 좋게 주차가 가능했지만, 주말이나 인기 날짜는 상황이 다를 수 있습니다.&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;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;처음 방문하시는 분께 추천드리는 관람 순서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경복궁 야간관람은 낮 관람처럼 모든 권역을 빠르게 훑는 방식보다, 조명이 아름다운 중심 권역을 천천히 보는 방식이 더 잘 맞았습니다. 특히 퇴근 후 방문하신다면 시간이 넉넉하지 않을 수 있으므로, 핵심 구간을 먼저 잡고 움직이시는 편이 좋습니다.&lt;/p&gt;
&lt;div class=&quot;gbk_route&quot;&gt;&lt;b&gt;개인적으로 추천드리는 야간관람 순서입니다.&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;경복궁 부설주차장 또는 인근 주차장에 주차합니다.&lt;/li&gt;
&lt;li&gt;광화문과 흥례문 방향으로 이동하여 입장 분위기를 먼저 느껴봅니다.&lt;/li&gt;
&lt;li&gt;해질녘 근정전을 먼저 보고, 정전의 웅장한 분위기를 사진으로 남깁니다.&lt;/li&gt;
&lt;li&gt;사정전과 흠경각 권역을 지나며 궁궐 내부의 조명과 현판, 전각의 디테일을 살펴봅니다.&lt;/li&gt;
&lt;li&gt;경회루로 이동한 뒤 바로 떠나지 말고, 어둠이 충분히 내려앉을 때까지 기다립니다.&lt;/li&gt;
&lt;li&gt;조명이 켜진 경회루와 연못 반영을 감상한 뒤 교태전&amp;middot;강녕전 권역을 천천히 둘러봅니다.&lt;/li&gt;
&lt;li&gt;퇴장 전 다시 근정전을 한 번 더 보고, 완전히 어두워진 뒤의 분위기를 비교해 봅니다.&lt;/li&gt;
&lt;li&gt;시간과 체력이 괜찮다면 광화문광장까지 걸어가 세종대왕 동상, 이순신 장군 동상, 감사의 정원을 함께 둘러봅니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사진 촬영 포인트와 개인적인 느낌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 방문에서 사진을 찍으며 가장 크게 느낀 점은, 경복궁 야간관람은 밝을 때와 어두울 때의 분위기가 완전히 다르다는 점입니다. 해질녘에는 하늘 색과 전각의 지붕선이 살아나고, 완전히 어두워진 뒤에는 조명과 그림자가 중심이 됩니다. 그래서 같은 장소라도 한 번만 찍고 지나가기보다는, 시간이 조금 지난 뒤 다시 찍어보는 것이 좋았습니다.&lt;/p&gt;
&lt;div class=&quot;gbk_tipbox&quot;&gt;&lt;b&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;광화문&amp;middot;흥례문 입구&lt;/b&gt;: 해질녘 하늘과 궁궐의 첫인상을 담기 좋습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;근정전 정면&lt;/b&gt;: 사람이 많아도 중심축이 분명해서 가장 대표적인 사진을 남기기 좋습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;근정전 내부 어좌와 일월오봉도&lt;/b&gt;: 왕의 권위를 상징하는 공간이라 역사적 의미를 함께 담기 좋습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사정전 현판과 내부&lt;/b&gt;: 정사를 논하던 편전의 분위기가 조명과 잘 어울립니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경회루 연못가&lt;/b&gt;: 완전히 어두워진 뒤 조명이 물에 비치는 순간이 가장 아름답습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;궁궐 담장과 오래된 문&lt;/b&gt;: 큰 전각과는 다른 고요한 디테일을 담기 좋습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;광화문광장&lt;/b&gt;: 세종대왕 동상, 이순신 장군 동상, 감사의 정원까지 함께 담을 수 있어 마무리 사진으로 좋습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 경회루는 꼭 시간을 두고 보시는 것을 추천드립니다. 처음 도착했을 때는 아직 노을이 남아 있었고, 많은 분들이 근처 의자에 앉아 어두워지기를 기다리고 있었습니다. 저도 그 흐름에 맞춰 잠시 앉아 기다렸는데, 조명이 선명해지는 순간 경회루의 분위기가 완전히 달라졌습니다. 야간관람의 핵심은 결국 이 기다림 속에 있었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;소요시간과 방문 만족도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴근 후 방문 기준으로 경복궁 내부 관람만 생각하면 약 1시간 30분 정도면 주요 권역을 볼 수 있었습니다. 다만 사진을 많이 찍거나 경회루 앞에서 어두워지기를 기다린다면 2시간 정도는 잡는 것이 좋습니다. 여기에 광화문광장 산책까지 더하면 전체 일정은 2시간 30분에서 3시간 정도로 생각하시면 여유롭습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&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;&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;그리고 경복궁 관람을 마친 뒤 광화문광장까지 이어 걸었던 시간도 좋았습니다. 세종대왕 동상과 이순신 장군 동상, 그리고 감사의 정원을 보며 과거의 궁궐에서 오늘의 대한민국으로 걸어 나오는 듯한 느낌이 들었습니다. 특히 6&amp;middot;25전쟁 참전국과 참전용사를 기억하는 감사의 정원은 취지가 분명한 공간이라 더 뜻깊게 다가왔습니다.&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;div class=&quot;gbk_quote&quot;&gt;하루의 끝에 만난 경복궁의 밤은 조용했지만 깊었습니다. 근정전의 위엄, 경회루의 반영, 광화문광장의 빛까지 이어진 길은 짧은 산책이 아니라 오래 기억될 밤의 기록이 되었습니다.&lt;/div&gt;
&lt;details&gt;
&lt;summary&gt;참고 자료 보기&lt;/summary&gt;
&lt;div class=&quot;gbk_source_list&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;경복궁 2026 상반기 야간관람 공식 공지: &lt;a href=&quot;https://royal.khs.go.kr/ROYAL/contents/R201000000.do?act=view&amp;amp;ceIdx=202604300270&amp;amp;selDate=2026-5-18&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://royal.khs.go.kr/ROYAL/contents/R201000000.do?act=view&amp;amp;ceIdx=202604300270&amp;amp;selDate=2026-5-18&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;경복궁 오시는 길&amp;middot;부설주차장 안내: &lt;a href=&quot;https://royal.khs.go.kr/ROYAL/contents/R707000000.do&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://royal.khs.go.kr/ROYAL/contents/R707000000.do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;경복궁 관람코스: &lt;a href=&quot;https://royal.khs.go.kr/ROYAL/contents/R701000000.do&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://royal.khs.go.kr/ROYAL/contents/R701000000.do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;한복 무료관람 가이드라인: &lt;a href=&quot;https://royal.khs.go.kr/ROYAL/contents/R705000000.do&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://royal.khs.go.kr/ROYAL/contents/R705000000.do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;경복궁 역사와 궁궐 설명: &lt;a href=&quot;https://www.heritage.go.kr/heri/html/HtmlPage.do?pg=%2Fpalaces%2FpalacesRoyalInfo.jsp&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.heritage.go.kr/heri/html/HtmlPage.do?pg=%2Fpalaces%2FpalacesRoyalInfo.jsp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;근정전 국가유산포털: &lt;a href=&quot;https://www.heritage.go.kr/heri/cul/culSelectDetail.do?ccbaCpno=1111102230000&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.heritage.go.kr/heri/cul/culSelectDetail.do?ccbaCpno=1111102230000&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;경회루 국가유산포털: &lt;a href=&quot;https://www.heritage.go.kr/heri/cul/culSelectDetail.do?ccbaCpno=1111102240000&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.heritage.go.kr/heri/cul/culSelectDetail.do?ccbaCpno=1111102240000&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;국립현대미술관 서울관 주차장 안내: &lt;a href=&quot;https://www.mmca.go.kr/seoul/facilityInfo/parkingLot.do&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.mmca.go.kr/seoul/facilityInfo/parkingLot.do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;광화문광장 감사의 정원 공식 안내: &lt;a href=&quot;https://gwanghwamun.seoul.go.kr/ghm/gratitudeGarden/list.do?mid=1360&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://gwanghwamun.seoul.go.kr/ghm/gratitudeGarden/list.do?mid=1360&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;서울시 감사의 정원 안내: &lt;a href=&quot;https://news.seoul.go.kr/culture/archives/532816&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://news.seoul.go.kr/culture/archives/532816&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;태그&lt;/h2&gt;
&lt;div class=&quot;gbk_tags&quot;&gt;&lt;span&gt;#경복궁&lt;/span&gt; &lt;span&gt;#경복궁야간관람&lt;/span&gt; &lt;span&gt;#경복궁야간개장&lt;/span&gt; &lt;span&gt;#2026경복궁야간관람&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;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>2026경복궁야간관람</category>
      <category>감사의빛</category>
      <category>경복궁</category>
      <category>경복궁야간개장</category>
      <category>경복궁야간관람</category>
      <category>경복궁주차장</category>
      <category>경희루</category>
      <category>광화문광장</category>
      <category>근정전</category>
      <category>서울야경</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/590</guid>
      <comments>https://odinbox.tistory.com/590#entry590comment</comments>
      <pubDate>Sat, 20 Jun 2026 18:18:12 +0900</pubDate>
    </item>
    <item>
      <title>지브리의 목소리를 만나다, 스튜디오 지브리 오리지널 싱어즈 첫 내한 공연 후기</title>
      <link>https://odinbox.tistory.com/589</link>
      <description>&lt;div&gt;
&lt;style&gt;
  .gibree_article {
    --gibree_navy: #0f2742;
    --gibree_deep: #102a45;
    --gibree_blue: #1f7dbb;
    --gibree_blue2: #55b7e8;
    --gibree_sky: #eaf6ff;
    --gibree_gold: #b48738;
    --gibree_gold2: #f2c46d;
    --gibree_ink: #1f2937;
    --gibree_body: #2f3d4d;
    --gibree_muted: #617182;
    --gibree_line: #d8e6f2;
    --gibree_card: #ffffff;
    --gibree_soft: #f7fbff;
    --gibree_shadow: 0 12px 30px rgba(15, 39, 66, 0.09);
    --gibree_shadow_hover: 0 22px 46px rgba(15, 39, 66, 0.16);

    max-width: 940px;
    margin: 0 auto;
    padding: 34px 18px 76px;
    background: #ffffff !important;
    color: var(--gibree_ink) !important;
    font-family: Pretendard, &quot;Noto Sans KR&quot;, &quot;Apple SD Gothic Neo&quot;, &quot;Malgun Gothic&quot;, sans-serif;
    line-height: 1.94;
    word-break: keep-all;
    letter-spacing: -0.02em;
  }

  .gibree_article * {
    box-sizing: border-box;
  }

  .gibree_article p,
  .gibree_article h1,
  .gibree_article h2,
  .gibree_article h3,
  .gibree_article h4,
  .gibree_article span,
  .gibree_article div,
  .gibree_article a {
    color: inherit;
  }

  .gibree_article a {
    color: var(--gibree_blue) !important;
    font-weight: 800;
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .gibree_article img {
    display: block !important;
    width: 100% !important;
    height: auto !important;
    margin: 0 auto !important;
    border-radius: 24px !important;
    box-shadow: 0 18px 44px rgba(15, 39, 66, 0.16) !important;
    border: 1px solid rgba(216, 230, 242, 0.95) !important;
    object-fit: contain !important;
  }

  .gibree_article .imageblock {
    max-width: 100% !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }

  @keyframes gibree_fade_up {
    from {
      opacity: 0;
      transform: translateY(22px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  @keyframes gibree_light_move {
    0% {
      background-position: 0% 50%;
    }
    100% {
      background-position: 100% 50%;
    }
  }

  @keyframes gibree_line_flow {
    0% {
      transform: translateX(-100%);
      opacity: 0;
    }
    30% {
      opacity: 1;
    }
    100% {
      transform: translateX(100%);
      opacity: 0;
    }
  }

  @keyframes gibree_soft_float {
    0%, 100% {
      transform: translateY(0);
    }
    50% {
      transform: translateY(-8px);
    }
  }

  .gibree_reveal {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 0.72s ease, transform 0.72s ease;
  }

  .gibree_reveal.gibree_is_visible {
    opacity: 1;
    transform: translateY(0);
  }

  .gibree_hero {
    position: relative;
    overflow: hidden;
    padding: 68px 34px 54px;
    border-radius: 34px;
    background:
      radial-gradient(circle at 15% 16%, rgba(80, 169, 224, 0.4), transparent 30%),
      radial-gradient(circle at 86% 13%, rgba(255, 220, 150, 0.22), transparent 34%),
      linear-gradient(135deg, #102a45 0%, #173b5f 48%, #0f2742 100%);
    border: 1px solid rgba(31, 125, 187, 0.3);
    box-shadow: 0 26px 58px rgba(15, 39, 66, 0.24);
    text-align: center;
    color: #ffffff !important;
    animation: gibree_fade_up 0.72s ease both;
  }

  .gibree_hero::before {
    content: &quot;&quot;;
    position: absolute;
    inset: 18px;
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 28px;
    pointer-events: none;
  }

  .gibree_hero::after {
    content: &quot;&quot;;
    position: absolute;
    left: -40%;
    bottom: 0;
    width: 80%;
    height: 2px;
    background: linear-gradient(90deg, transparent, rgba(155, 215, 255, 0.8), transparent);
    animation: gibree_line_flow 4.2s ease-in-out infinite;
  }

  .gibree_label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 7px 18px;
    margin-bottom: 24px;
    border-radius: 999px;
    background: linear-gradient(90deg, #2f94d1, #55b7e8, #2f94d1);
    background-size: 220% 220%;
    color: #ffffff !important;
    font-size: 13px;
    font-weight: 900;
    letter-spacing: 0.1em;
    animation: gibree_light_move 3.8s ease-in-out infinite alternate;
  }

  .gibree_title {
    margin: 0 auto;
    max-width: 820px;
    color: #ffffff !important;
    font-size: clamp(31px, 5vw, 52px);
    line-height: 1.3;
    font-weight: 900;
    letter-spacing: -0.047em;
  }

  .gibree_subtitle {
    max-width: 760px;
    margin: 22px auto 0;
    color: #d9ecfa !important;
    font-size: 17px;
    line-height: 1.96;
    font-weight: 500;
  }

  .gibree_thumb_wrap {
    max-width: 420px;
    margin: 34px auto 0;
    animation: gibree_soft_float 4.8s ease-in-out infinite;
  }

  .gibree_thumb_wrap img {
    border-radius: 32px !important;
  }

  .gibree_meta_grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin: 32px 0 40px;
  }

  .gibree_meta_card {
    padding: 21px 22px;
    border-radius: 21px;
    background: #f7fbff;
    border: 1px solid var(--gibree_line);
    box-shadow: 0 8px 22px rgba(15, 39, 66, 0.06);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
  }

  .gibree_meta_card:hover {
    transform: translateY(-4px);
    box-shadow: var(--gibree_shadow_hover);
  }

  .gibree_meta_label {
    display: block;
    margin-bottom: 8px;
    color: var(--gibree_blue) !important;
    font-size: 13px;
    font-weight: 900;
  }

  .gibree_meta_value {
    display: block;
    color: var(--gibree_navy) !important;
    font-size: 17px;
    font-weight: 900;
  }

  .gibree_toc {
    margin: 38px 0 46px;
    padding: 24px;
    border-radius: 26px;
    background: linear-gradient(135deg, #f7fbff 0%, #fffaf0 100%);
    border: 1px solid #dce9f3;
    box-shadow: 0 10px 26px rgba(15, 39, 66, 0.06);
  }

  .gibree_toc_title {
    margin: 0 0 14px;
    color: var(--gibree_navy) !important;
    font-size: 20px;
    font-weight: 900;
  }

  .gibree_toc_grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }

  .gibree_toc_link {
    display: block;
    padding: 12px 14px;
    border-radius: 16px;
    background: #ffffff;
    border: 1px solid #e1edf7;
    color: #23435c !important;
    font-size: 14.5px;
    font-weight: 900;
    text-decoration: none !important;
    transition: transform 0.22s ease, border-color 0.22s ease, background 0.22s ease;
  }

  .gibree_toc_link:hover {
    transform: translateY(-3px);
    border-color: #9fcfed;
    background: #f1f8ff;
  }

  .gibree_editorial_box {
    margin: 40px 0;
    padding: 30px;
    border-radius: 28px;
    background: linear-gradient(135deg, #fffaf0 0%, #f6fbff 100%);
    border: 1px solid #ead8b8;
    box-shadow: 0 12px 30px rgba(180, 135, 56, 0.08);
  }

  .gibree_editorial_title {
    margin: 0 0 14px;
    color: #835900 !important;
    font-size: 22px;
    font-weight: 900;
  }

  .gibree_editorial_text {
    margin: 0;
    color: #344256 !important;
    font-size: 16.5px;
    line-height: 1.96;
  }

  .gibree_score_grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 12px;
    margin: 24px 0 0;
  }

  .gibree_score_card {
    padding: 17px 12px;
    border-radius: 20px;
    background: #ffffff;
    border: 1px solid #e3edf6;
    text-align: center;
    transition: transform 0.24s ease, box-shadow 0.24s ease;
  }

  .gibree_score_card:hover {
    transform: translateY(-4px);
    box-shadow: var(--gibree_shadow);
  }

  .gibree_score_name {
    display: block;
    margin-bottom: 6px;
    color: var(--gibree_muted) !important;
    font-size: 13px;
    font-weight: 900;
  }

  .gibree_score_value {
    display: block;
    color: var(--gibree_navy) !important;
    font-size: 22px;
    font-weight: 900;
  }

  .gibree_section {
    margin-top: 64px;
  }

  .gibree_section_head {
    margin-bottom: 25px;
    text-align: center;
  }

  .gibree_section_kicker {
    display: block;
    margin-bottom: 8px;
    color: var(--gibree_gold) !important;
    font-size: 13px;
    font-weight: 900;
    letter-spacing: 0.18em;
  }

  .gibree_section_title {
    position: relative;
    display: inline-block;
    margin: 0;
    padding: 0 24px;
    color: var(--gibree_navy) !important;
    font-size: clamp(24px, 4vw, 34px);
    line-height: 1.35;
    font-weight: 900;
    letter-spacing: -0.04em;
  }

  .gibree_section_title::before,
  .gibree_section_title::after {
    content: &quot;&quot;;
    position: absolute;
    top: 50%;
    width: 48px;
    height: 1px;
    background: var(--gibree_line);
  }

  .gibree_section_title::before {
    right: 100%;
  }

  .gibree_section_title::after {
    left: 100%;
  }

  .gibree_paragraph {
    margin: 0 0 18px;
    color: var(--gibree_body) !important;
    font-size: 17px;
    line-height: 1.98;
  }

  .gibree_paragraph strong {
    color: var(--gibree_navy) !important;
    font-weight: 900;
  }

  .gibree_quote {
    margin: 32px 0;
    padding: 28px 30px;
    border-radius: 25px;
    background: #f1f8ff;
    border-left: 6px solid var(--gibree_blue);
    color: #153c5c !important;
    font-size: 19px;
    line-height: 1.82;
    font-weight: 900;
  }

  .gibree_photo {
    max-width: 860px;
    margin: 38px auto 38px;
    padding: 16px 16px 20px;
    border-radius: 30px;
    background: #f7fbff;
    border: 1px solid var(--gibree_line);
    box-shadow: 0 10px 28px rgba(15, 39, 66, 0.07);
  }

  .gibree_photo.gibree_photo_portrait {
    max-width: 680px;
  }

  .gibree_photo p {
    margin: 0 !important;
  }

  .gibree_caption {
    margin: 16px auto 0;
    padding: 18px 20px;
    border-radius: 20px;
    background: #ffffff;
    border: 1px solid #e3edf6;
    color: #40566a !important;
    font-size: 15px;
    line-height: 1.75;
    text-align: center;
    font-weight: 700;
  }

  .gibree_caption strong {
    display: block;
    margin-bottom: 5px;
    color: var(--gibree_navy) !important;
    font-size: 16px;
    font-weight: 900;
  }

  .gibree_cast_grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 17px;
    margin-top: 28px;
  }

  .gibree_cast_card {
    position: relative;
    overflow: hidden;
    padding: 26px;
    border-radius: 24px;
    background: var(--gibree_card);
    border: 1px solid var(--gibree_line);
    box-shadow: 0 10px 28px rgba(15, 39, 66, 0.07);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
  }

  .gibree_cast_card::before {
    content: &quot;&quot;;
    position: absolute;
    inset: 0;
    width: 5px;
    background: linear-gradient(180deg, #2f94d1, #f2c46d);
  }

  .gibree_cast_card:hover {
    transform: translateY(-5px);
    box-shadow: var(--gibree_shadow_hover);
  }

  .gibree_cast_name {
    margin: 0 0 10px;
    color: var(--gibree_navy) !important;
    font-size: 21px;
    font-weight: 900;
  }

  .gibree_cast_role {
    display: inline-block;
    margin-bottom: 15px;
    padding: 5px 11px;
    border-radius: 999px;
    background: var(--gibree_sky);
    color: var(--gibree_blue) !important;
    font-size: 12px;
    font-weight: 900;
  }

  .gibree_cast_text {
    margin: 0 0 14px;
    color: #3c4a59 !important;
    font-size: 15.7px;
    line-height: 1.9;
  }

  .gibree_cast_note {
    margin: 16px 0 0;
    padding: 14px 15px;
    border-radius: 16px;
    background: #fffaf0;
    border: 1px solid #ead8b8;
    color: #60420c !important;
    font-size: 14.5px;
    line-height: 1.8;
    font-weight: 800;
  }

  .gibree_program_block,
  .gibree_stage_box,
  .gibree_emotion_box,
  .gibree_faq_box {
    margin-top: 28px;
    padding: 29px;
    border-radius: 27px;
    background: #f8fbff;
    border: 1px solid var(--gibree_line);
  }

  .gibree_program_block {
    position: relative;
    overflow: hidden;
  }

  .gibree_program_block::before {
    content: &quot;&quot;;
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: linear-gradient(90deg, var(--gibree_blue), var(--gibree_gold2), var(--gibree_blue2));
    background-size: 200% 200%;
    animation: gibree_light_move 4.4s ease-in-out infinite alternate;
  }

  .gibree_part_title,
  .gibree_stage_title,
  .gibree_emotion_title,
  .gibree_faq_title {
    margin: 0 0 18px;
    color: var(--gibree_navy) !important;
    font-size: 22px;
    font-weight: 900;
  }

  .gibree_part_title {
    text-align: center;
    color: var(--gibree_blue) !important;
    font-size: 23px;
  }

  .gibree_song_list {
    display: grid;
    gap: 15px;
  }

  .gibree_song_card {
    padding: 23px;
    border-radius: 21px;
    background: #ffffff;
    border: 1px solid #e0edf7;
    box-shadow: 0 8px 20px rgba(15, 39, 66, 0.05);
    transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
  }

  .gibree_song_card:hover {
    transform: translateY(-4px);
    border-color: #9fcfed;
    box-shadow: var(--gibree_shadow);
  }

  .gibree_song_title {
    margin: 0 0 6px;
    color: var(--gibree_navy) !important;
    font-size: 19.5px;
    font-weight: 900;
  }

  .gibree_song_meta {
    margin: 0 0 12px;
    color: var(--gibree_blue) !important;
    font-size: 14px;
    font-weight: 800;
  }

  .gibree_song_desc,
  .gibree_stage_text,
  .gibree_emotion_text,
  .gibree_faq_text {
    margin: 0 0 16px;
    color: #394858 !important;
    font-size: 15.8px;
    line-height: 1.9;
  }

  .gibree_stage_point {
    margin: 18px 0 0;
    padding: 17px 18px;
    border-radius: 18px;
    background: #ffffff;
    border: 1px solid #e3edf6;
    color: #23435c !important;
    font-size: 15.5px;
    line-height: 1.85;
    font-weight: 800;
  }

  .gibree_review_grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 17px;
    margin-top: 25px;
  }

  .gibree_review_card {
    padding: 25px;
    border-radius: 23px;
    background: #fffaf0;
    border: 1px solid #ead8b8;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
  }

  .gibree_review_card:hover {
    transform: translateY(-4px);
    box-shadow: var(--gibree_shadow);
  }

  .gibree_review_card.gibree_review_card_blue {
    background: #f1f8ff;
    border-color: #cfe5f7;
  }

  .gibree_review_card_title {
    margin: 0 0 12px;
    color: #855c08 !important;
    font-size: 20px;
    font-weight: 900;
  }

  .gibree_review_card_blue .gibree_review_card_title {
    color: var(--gibree_blue) !important;
  }

  .gibree_review_card_text {
    margin: 0;
    color: #374151 !important;
    font-size: 15.7px;
    line-height: 1.9;
  }

  .gibree_final_box {
    margin-top: 32px;
    padding: 30px;
    border-radius: 28px;
    background:
      radial-gradient(circle at 10% 12%, rgba(85, 183, 232, 0.18), transparent 28%),
      linear-gradient(135deg, #102a45 0%, #173b5f 100%);
    color: #ffffff !important;
    box-shadow: 0 18px 40px rgba(15, 39, 66, 0.18);
  }

  .gibree_final_title {
    margin: 0 0 14px;
    color: #ffffff !important;
    font-size: 23px;
    font-weight: 900;
  }

  .gibree_final_text {
    margin: 0 0 14px;
    color: #d9ecfa !important;
    font-size: 16.5px;
    line-height: 1.95;
  }

  .gibree_footer_note {
    margin-top: 56px;
    padding: 28px;
    border-radius: 25px;
    background: #102a45;
    color: #ffffff !important;
  }

  .gibree_footer_note_title {
    margin: 0 0 12px;
    color: #ffffff !important;
    font-size: 22px;
    font-weight: 900;
  }

  .gibree_footer_note_text {
    margin: 0 0 12px;
    color: #d9ecfa !important;
    font-size: 16px;
    line-height: 1.9;
  }

  .gibree_footer_note a {
    color: #9bd7ff !important;
    font-weight: 800;
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  @media (max-width: 820px) {
    .gibree_score_grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .gibree_score_card:last-child {
      grid-column: 1 / -1;
    }
  }

  @media (max-width: 720px) {
    .gibree_article {
      padding: 24px 12px 48px;
    }

    .gibree_hero {
      padding: 44px 22px 38px;
      border-radius: 25px;
    }

    .gibree_meta_grid,
    .gibree_cast_grid,
    .gibree_review_grid,
    .gibree_toc_grid {
      grid-template-columns: 1fr;
    }

    .gibree_section_title::before,
    .gibree_section_title::after {
      display: none;
    }

    .gibree_program_block,
    .gibree_stage_box,
    .gibree_emotion_box,
    .gibree_editorial_box,
    .gibree_final_box,
    .gibree_toc,
    .gibree_faq_box {
      padding: 20px;
    }

    .gibree_paragraph {
      font-size: 16px;
    }

    .gibree_score_grid {
      grid-template-columns: 1fr;
    }

    .gibree_score_card:last-child {
      grid-column: auto;
    }

    .gibree_photo {
      padding: 10px 10px 14px;
      border-radius: 22px;
    }

    .gibree_article img {
      border-radius: 17px !important;
    }

    .gibree_caption {
      border-radius: 16px;
      font-size: 14.5px;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .gibree_article *,
    .gibree_article *::before,
    .gibree_article *::after {
      animation: none !important;
      transition: none !important;
      scroll-behavior: auto !important;
    }

    .gibree_reveal {
      opacity: 1;
      transform: none;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;article class=&quot;gibree_article&quot;&gt;&lt;header class=&quot;gibree_hero&quot;&gt;&lt;span class=&quot;gibree_label&quot;&gt;CONCERT REVIEW&lt;/span&gt;
&lt;h1 class=&quot;gibree_title&quot;&gt;지브리의 목소리를 만나다&lt;/h1&gt;
&lt;p class=&quot;gibree_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;스튜디오 지브리 오리지널 싱어즈 첫 내한 공연 후기입니다. 영화 속 장면으로만 기억하던 노래가 실제 무대 위에서 다시 살아났고, 연세대학교 대강당의 여름밤은 오래 기억에 남을 음악의 시간으로 채워졌습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_thumb_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (3).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b639yQ/dJMcadWzdU7/zPiJ2KrtrqyaK69ewnZWRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b639yQ/dJMcadWzdU7/zPiJ2KrtrqyaK69ewnZWRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b639yQ/dJMcadWzdU7/zPiJ2KrtrqyaK69ewnZWRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb639yQ%2FdJMcadWzdU7%2FzPiJ2KrtrqyaK69ewnZWRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (3).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;section class=&quot;gibree_meta_grid gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_meta_card&quot;&gt;&lt;span class=&quot;gibree_meta_label&quot;&gt;공연명&lt;/span&gt; &lt;span class=&quot;gibree_meta_value&quot;&gt;The Music of STUDIO GHIBLI Original Singers Symphony&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_meta_card&quot;&gt;&lt;span class=&quot;gibree_meta_label&quot;&gt;장소&lt;/span&gt; &lt;span class=&quot;gibree_meta_value&quot;&gt;연세대학교 대강당&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_meta_card&quot;&gt;&lt;span class=&quot;gibree_meta_label&quot;&gt;관람일&lt;/span&gt; &lt;span class=&quot;gibree_meta_value&quot;&gt;2026년 6월 6일 토요일 19:30&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_meta_card&quot;&gt;&lt;span class=&quot;gibree_meta_label&quot;&gt;공연 구성&lt;/span&gt; &lt;span class=&quot;gibree_meta_value&quot;&gt;120분 공연, 인터미션 15분 포함&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;nav class=&quot;gibree_toc gibree_reveal&quot;&gt;
&lt;h2 class=&quot;gibree_toc_title&quot; data-ke-size=&quot;size26&quot;&gt;Review Index&lt;/h2&gt;
&lt;div class=&quot;gibree_toc_grid&quot;&gt;&lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_walk&quot;&gt;공연장으로 향하던 길&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_campus&quot;&gt;연세대학교 캠퍼스 기록&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_cast&quot;&gt;오리지널 싱어즈 리뷰&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_program1&quot;&gt;1부 프로그램 감상&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_program2&quot;&gt;2부 프로그램 감상&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_stage&quot;&gt;무대 연출 평가&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_photo&quot;&gt;공연 마지막 포토타임&lt;/a&gt; &lt;a class=&quot;gibree_toc_link&quot; href=&quot;#gibree_section_epilogue&quot;&gt;마무리 후기&lt;/a&gt;&lt;/div&gt;
&lt;/nav&gt;
&lt;section class=&quot;gibree_editorial_box gibree_reveal&quot;&gt;
&lt;h2 class=&quot;gibree_editorial_title&quot; data-ke-size=&quot;size26&quot;&gt;한 줄 총평&lt;/h2&gt;
&lt;p class=&quot;gibree_editorial_text&quot; data-ke-size=&quot;size16&quot;&gt;이번 공연은 단순히 지브리 OST를 감상하는 시간이 아니었습니다. 원곡을 불렀던 가수들의 목소리, 오케스트라의 라이브 연주, 작품을 기억하는 관객들의 감정이 한 공간에서 만난 공연이었습니다. 무대 연출에서는 약간의 아쉬움도 있었지만, 음악과 목소리가 가진 힘만큼은 충분히 강했고 오래 남았습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_score_grid&quot;&gt;
&lt;div class=&quot;gibree_score_card&quot;&gt;&lt;span class=&quot;gibree_score_name&quot;&gt;음악성&lt;/span&gt; &lt;span class=&quot;gibree_score_value&quot;&gt;9.5&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_score_card&quot;&gt;&lt;span class=&quot;gibree_score_name&quot;&gt;현장감&lt;/span&gt; &lt;span class=&quot;gibree_score_value&quot;&gt;9.0&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_score_card&quot;&gt;&lt;span class=&quot;gibree_score_name&quot;&gt;출연진&lt;/span&gt; &lt;span class=&quot;gibree_score_value&quot;&gt;9.4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_score_card&quot;&gt;&lt;span class=&quot;gibree_score_name&quot;&gt;무대 연출&lt;/span&gt; &lt;span class=&quot;gibree_score_value&quot;&gt;7.8&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gibree_score_card&quot;&gt;&lt;span class=&quot;gibree_score_name&quot;&gt;재관람 의사&lt;/span&gt; &lt;span class=&quot;gibree_score_value&quot;&gt;9.2&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_walk&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;PROLOGUE&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;공연장으로 향하던 길&lt;/h2&gt;
&lt;/div&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;원래는 직접 예매를 해서 보러 갈 생각이었습니다. 그런데 운 좋게도 기대평 이벤트에 당첨되어 초대권을 받게 되었고, 조금은 더 특별한 마음으로 연세대학교 대강당을 찾게 되었습니다. 제가 좋아하는 지브리 음악을, 그것도 오리지널 싱어즈의 목소리로 직접 들을 수 있다는 점만으로도 공연 전부터 충분히 설레는 시간이었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;만약 울산에서 올라왔다면 꽤 힘든 일정이었을 것 같습니다. 하지만 지금은 광명에 있다 보니 비교적 편하게 다녀올 수 있었습니다. 처음 가본 연세대학교 신촌캠퍼스는 생각보다 훨씬 넓고 아름다웠습니다. 오래된 건물들이 주는 분위기, 캠퍼스 특유의 차분함, 그리고 병원과 함께 이어진 큰 규모의 공간이 인상적으로 다가왔습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_photo gibree_photo_portrait&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYnwsA/dJMcahrbMHs/aWIDOm2NmXzXuiuquGsZEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYnwsA/dJMcahrbMHs/aWIDOm2NmXzXuiuquGsZEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYnwsA/dJMcahrbMHs/aWIDOm2NmXzXuiuquGsZEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYnwsA%2FdJMcahrbMHs%2FaWIDOm2NmXzXuiuquGsZEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;공연 전, 티켓을 받고 남긴 기록&lt;/b&gt; 연세대학교 대강당 앞에서 티켓을 들고 남긴 사진입니다. 공연이 시작되기 전의 설렘이 가장 선명하게 남아 있는 장면입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmqeNe/dJMcacwC3pa/Qu1DkTLCeQUeIKJKFIDyk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmqeNe/dJMcacwC3pa/Qu1DkTLCeQUeIKJKFIDyk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmqeNe/dJMcacwC3pa/Qu1DkTLCeQUeIKJKFIDyk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmqeNe%2FdJMcacwC3pa%2FQu1DkTLCeQUeIKJKFIDyk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;연세대학교 계단의 풍경&lt;/b&gt; 공연장으로 향하기 전 바라본 캠퍼스의 모습입니다. 공연 전 산책하듯 둘러보기에도 좋은 분위기였습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_quote&quot;&gt;이 공연을 한마디로 표현하면 &amp;ldquo;귀가 호강한 시간&amp;rdquo;이었습니다. 조금 더 정확히 말하면, 귀뿐 아니라 오래된 추억과 마음 한편까지 함께 따뜻해진 시간이었습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_campus&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;YONSEI CAMPUS&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;공연 전 둘러본 연세대학교&lt;/h2&gt;
&lt;/div&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;공연을 보러 간 날이었지만, 연세대학교 캠퍼스 자체도 기억에 많이 남았습니다. 붉은 벽돌과 고풍스러운 건물, 넓은 길, 오래된 학교가 가진 차분한 분위기가 공연 전의 마음을 더 천천히 가라앉혀 주었습니다. 지브리 음악을 들으러 가는 길에 이런 캠퍼스 풍경을 먼저 마주하니, 공연 전부터 이미 조금은 영화 같은 하루가 시작된 느낌이었습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_photo gibree_photo_portrait&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o0eqr/dJMcaci1VdF/SiXS4wjfbTTUSffwTZGh51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o0eqr/dJMcaci1VdF/SiXS4wjfbTTUSffwTZGh51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o0eqr/dJMcaci1VdF/SiXS4wjfbTTUSffwTZGh51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo0eqr%2FdJMcaci1VdF%2FSiXS4wjfbTTUSffwTZGh51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;언더우드 동상&lt;/b&gt; 연세대학교 신촌캠퍼스에서 만난 언더우드 동상입니다. 캠퍼스의 역사적인 분위기를 가장 먼저 느끼게 해준 장면이었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo gibree_photo_portrait&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNCde1/dJMcaaZQWdj/bluw4YDi6Zas6xGniIMvk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNCde1/dJMcaaZQWdj/bluw4YDi6Zas6xGniIMvk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNCde1/dJMcaaZQWdj/bluw4YDi6Zas6xGniIMvk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNCde1%2FdJMcaaZQWdj%2Fbluw4YDi6Zas6xGniIMvk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;고풍스러운 연세대 건물&lt;/b&gt; 오래된 건물이 주는 분위기가 좋았습니다. 공연장에 가기 전부터 캠퍼스 자체가 하나의 배경처럼 느껴졌습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo gibree_photo_portrait&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1rYD0/dJMcaglsnNE/ztDHPHku0RotCVcD47D4Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1rYD0/dJMcaglsnNE/ztDHPHku0RotCVcD47D4Nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1rYD0/dJMcaglsnNE/ztDHPHku0RotCVcD47D4Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1rYD0%2FdJMcaglsnNE%2FztDHPHku0RotCVcD47D4Nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;캠퍼스 산책 중 만난 풍경&lt;/b&gt; 건물의 질감과 주변 분위기가 좋아서 자연스럽게 사진을 남기게 되었습니다. 공연 전의 시간이 천천히 깊어지는 느낌이었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qU52j/dJMcacciUnZ/Al6iwepo5Wt5FDtdK7Jr01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qU52j/dJMcacciUnZ/Al6iwepo5Wt5FDtdK7Jr01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qU52j/dJMcacciUnZ/Al6iwepo5Wt5FDtdK7Jr01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqU52j%2FdJMcacciUnZ%2FAl6iwepo5Wt5FDtdK7Jr01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;넓게 바라본 연세대학교 건물&lt;/b&gt; 캠퍼스가 생각보다 훨씬 넓었고, 건물들이 주는 분위기도 좋아 공연 전부터 기분이 좋았습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo gibree_photo_portrait&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBLS76/dJMcaaMjLrU/qKvQTCC54RtEnjXhV4ycFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBLS76/dJMcaaMjLrU/qKvQTCC54RtEnjXhV4ycFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBLS76/dJMcaaMjLrU/qKvQTCC54RtEnjXhV4ycFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBLS76%2FdJMcaaMjLrU%2FqKvQTCC54RtEnjXhV4ycFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;추모 행사가 진행 중이던 캠퍼스&lt;/b&gt; 이날 연세대학교에서는 추모 관련 행사도 진행되고 있었습니다. 공연 전의 들뜬 마음과는 또 다른 차분함이 느껴졌습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmbALB/dJMcagsePjN/ZlRhkhbgiq0BipGq5lvukk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmbALB/dJMcagsePjN/ZlRhkhbgiq0BipGq5lvukk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmbALB/dJMcagsePjN/ZlRhkhbgiq0BipGq5lvukk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmbALB%2FdJMcagsePjN%2FZlRhkhbgiq0BipGq5lvukk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;캠퍼스 안의 또 다른 분위기&lt;/b&gt; 공연을 보러 온 날이었지만, 캠퍼스 곳곳의 장면들이 하루의 기억을 더 풍부하게 만들어주었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_cast&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;CAST FOCUS&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;무대에서 만난 오리지널 싱어즈&lt;/h2&gt;
&lt;/div&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;이번 공연에서 특히 좋았던 점은 곡만 연달아 들려주는 방식이 아니었다는 점입니다. 1~2곡씩 묶어 무대를 보여준 뒤, 중간중간 출연진의 인터뷰가 이어졌습니다. 덕분에 가수분들이 어떤 마음으로 노래를 불렀는지, 한국 관객을 어떻게 바라보고 있는지, 그리고 각 곡이 어떤 의미로 남아 있는지를 조금 더 가까이 느낄 수 있었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;무엇보다 인상 깊었던 것은 모든 출연진이 서툰 한국어라도 직접 한국 팬들과 소통하려고 했다는 점입니다. 완벽한 발음이나 유창한 표현보다 더 크게 다가온 것은 그 안에 담긴 진심이었습니다. 관객에게 한 걸음 더 다가오려는 마음이 느껴졌고, 그 순간 공연장은 단순한 관람의 공간이 아니라 서로의 추억을 나누는 따뜻한 공간처럼 느껴졌습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_cast_grid&quot;&gt;
&lt;div class=&quot;gibree_cast_card&quot;&gt;
&lt;h3 class=&quot;gibree_cast_name&quot; data-ke-size=&quot;size23&quot;&gt;시마모토 스미&lt;/h3&gt;
&lt;span class=&quot;gibree_cast_role&quot;&gt;Voice Acting Moment&lt;/span&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;시마모토 스미님은 무대 위에서 목소리라는 예술이 가진 힘을 직접 보여주셨습니다. 특히 더빙과 관련된 짧은 시연은 공연 전체에서 가장 인상 깊었던 순간 중 하나였습니다. 아주 짧은 맛보기였지만, 목소리 하나로 공연장의 공기가 바뀌는 느낌이었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;대사 한마디에 인물의 성격, 장면의 분위기, 작품의 감정이 함께 실리는 것을 보며 감탄하게 되었습니다. 왜 많은 사람들이 시마모토 스미님을 일본 성우계의 전설처럼 이야기하는지 자연스럽게 이해할 수 있었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_note&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로는 &amp;ldquo;목소리 하나로 장면이 만들어진다&amp;rdquo;는 말을 가장 실감한 순간이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_cast_card&quot;&gt;
&lt;h3 class=&quot;gibree_cast_name&quot; data-ke-size=&quot;size23&quot;&gt;키무라 유미&lt;/h3&gt;
&lt;span class=&quot;gibree_cast_role&quot;&gt;Always with Me&lt;/span&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;키무라 유미님의 무대는 조용하지만 깊었습니다. 인터뷰에서 몸 상태가 좋지 않아 걱정이 많았다고 이야기하셨지만, 실제 무대에서는 그런 느낌이 거의 들지 않았습니다. 오히려 담담하게 노래를 이어가는 모습에서 더 큰 울림이 느껴졌습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;「언제나 몇 번이라도」가 시작되었을 때는 공연장의 분위기가 순간적으로 차분해졌습니다. 키무라 유미님의 목소리로 직접 들으니 「센과 치히로의 행방불명」 마지막에 남았던 여운이 다시 살아나는 듯했습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_note&quot; data-ke-size=&quot;size16&quot;&gt;몸 상태가 좋지 않았다는 이야기를 듣고 걱정도 되었지만, 끝까지 무대를 잘 마무리해주셔서 감사한 마음이 들었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_cast_card&quot;&gt;
&lt;h3 class=&quot;gibree_cast_name&quot; data-ke-size=&quot;size23&quot;&gt;이노우에 아즈미&lt;/h3&gt;
&lt;span class=&quot;gibree_cast_role&quot;&gt;Totoro &amp;middot; Laputa &amp;middot; Kiki&lt;/span&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;이노우에 아즈미님은 「천공의 성 라퓨타」, 「이웃집 토토로」, 「마녀 배달부 키키」의 추억을 한 번에 불러오는 목소리였습니다. 휠체어를 타고 무대에 오르셨지만, 노래가 시작되는 순간에는 그 사실보다 음악이 먼저 다가왔습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;익숙한 멜로디가 실제 목소리로 들리니 감정의 밀도가 달랐고, 한 곡 한 곡이 오래된 필름처럼 마음속에서 다시 재생되는 느낌이었습니다. 특히 토토로와 라퓨타의 곡들은 &amp;ldquo;아, 이 목소리였지&amp;rdquo;라는 생각이 자연스럽게 들 정도로 반가웠습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_note&quot; data-ke-size=&quot;size16&quot;&gt;긴 시간을 지나 다시 관객 앞에서 노래한다는 것 자체가 큰 감동이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_cast_card&quot;&gt;
&lt;h3 class=&quot;gibree_cast_name&quot; data-ke-size=&quot;size23&quot;&gt;유유&lt;/h3&gt;
&lt;span class=&quot;gibree_cast_role&quot;&gt;Lovely Stage Moment&lt;/span&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;유유님은 이노우에 아즈미님의 딸로 알려진 가수입니다. 두 사람이 함께 무대에 있는 모습은 그 자체로 따뜻했습니다. 지브리 음악이 한 세대의 추억에서 끝나는 것이 아니라, 다음 세대로 이어지고 있다는 느낌을 받았습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;그리고 개인적으로 유유님은 정말 귀여웠습니다. 말투도 그렇고, 무대 위에서 보여주는 작은 리액션이나 행동들이 전체적으로 사랑스럽게 느껴졌습니다. 과하게 꾸민 귀여움이 아니라, 자연스럽게 나오는 밝고 순수한 분위기가 있었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;무대에서는 노래도 잘하셨지만, 그보다 더 오래 남는 것은 사람 자체가 주는 밝은 에너지였습니다. 혼자 이야기하거나 반응할 때는 공연장 분위기를 부드럽게 만들어주는 역할을 해주셨습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_note&quot; data-ke-size=&quot;size16&quot;&gt;유유님은 노래도 좋았지만, 말투와 행동이 너무 귀여워서 공연의 분위기를 한층 더 따뜻하고 사랑스럽게 만들어주셨습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_cast_card&quot;&gt;
&lt;h3 class=&quot;gibree_cast_name&quot; data-ke-size=&quot;size23&quot;&gt;요네라 요시카즈&lt;/h3&gt;
&lt;span class=&quot;gibree_cast_role&quot;&gt;Princess Mononoke&lt;/span&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;요네라 요시카즈님의 무대는 공연 전체에서 가장 신비롭고 강렬한 축에 가까웠습니다. 「모노노케 히메」는 지브리 음악 중에서도 단순히 아름답다고만 표현하기 어려운 곡입니다. 숲, 생명, 인간의 욕망, 자연과 문명의 충돌 같은 작품의 무게가 함께 담겨 있기 때문입니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;높고 섬세한 음색이 대강당에 울릴 때, 공연장의 분위기가 확실히 달라졌습니다. 아름답지만 가볍지 않았고, 조용하지만 깊은 힘이 있었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_note&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로는 1부에서 가장 묵직하게 남은 무대였습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_cast_card&quot;&gt;
&lt;h3 class=&quot;gibree_cast_name&quot; data-ke-size=&quot;size23&quot;&gt;도쿄 아시아 오케스트라&lt;/h3&gt;
&lt;span class=&quot;gibree_cast_role&quot;&gt;Live Orchestra&lt;/span&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;도쿄 아시아 오케스트라는 이번 공연의 중심을 안정적으로 받쳐주었습니다. 오케스트라는 노래를 과하게 덮지 않고, 각 곡의 정서를 잘 살려주는 방식으로 연주했습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_text&quot; data-ke-size=&quot;size16&quot;&gt;현악기의 부드러운 결, 관악기의 깊은 호흡, 곡이 끝난 뒤 남는 잔향까지 공연의 완성도를 높여주었습니다. 익숙한 멜로디가 라이브 악기와 만나니 영화 속 배경음악이 아니라 지금 이 자리에서 살아 움직이는 음악처럼 느껴졌습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_cast_note&quot; data-ke-size=&quot;size16&quot;&gt;지브리 음악은 오케스트라로 들을 때 장면의 크기와 감정의 깊이가 더 선명하게 살아났습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_program1&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;PROGRAM REVIEW&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;1부 프로그램 감상&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_program_block&quot;&gt;
&lt;h3 class=&quot;gibree_part_title&quot; data-ke-size=&quot;size23&quot;&gt;1부&lt;/h3&gt;
&lt;div class=&quot;gibree_song_list&quot;&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;그대를 태우고&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;천공의 성 라퓨타 OST &amp;middot; Carrying You&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;첫 곡으로 매우 잘 어울리는 선택이었습니다. 라퓨타의 하늘, 오래된 성, 소년과 소녀의 모험이 자연스럽게 떠올랐습니다. 공연의 시작부터 관객의 기억을 무대 안으로 끌어오는 힘이 있었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;산책&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;이웃집 토토로 OST &amp;middot; Hey Let&amp;rsquo;s Go&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;「산책」은 듣는 순간 공연장의 분위기를 밝게 바꾸는 곡이었습니다. 아이가 길을 나서는 듯한 경쾌함이 있어 관객들도 마음속으로 함께 걸어가는 느낌이 들었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;마녀 배달부 키키 메들리&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;Kiki&amp;rsquo;s Delivery Service Medley&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;키키의 음악은 성장의 느낌이 강하게 담겨 있었습니다. 낯선 도시에서 혼자 버티는 마음, 그래도 다시 날아오르려는 마음이 메들리 안에서 자연스럽게 이어졌습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;불꽃의 보물&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;루팡 3세 칼리오스트로의 성 &amp;middot; Fire Treasure&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;지브리 작품으로만 묶이기보다는 미야자키 하야오 감독의 초기 감성과 연결되는 곡처럼 느껴졌습니다. 낭만적이고 고전적인 분위기가 있었고, 공연의 색을 조금 더 넓혀주는 역할을 했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;인생의 회전목마&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;하울의 움직이는 성 OST &amp;middot; Merry-Go-Round of Life&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;이 곡은 제목처럼 선율이 빙글빙글 돌면서 감정을 천천히 끌어올렸습니다. 화려하면서도 쓸쓸하고, 낭만적이면서도 묘하게 아련했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;세계의 약속&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;하울의 움직이는 성 OST &amp;middot; The Promise of the World&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;「세계의 약속」은 마음을 천천히 가라앉히는 곡이었습니다. 사랑, 시간, 기다림 같은 단어들이 떠오르는 조용한 여운이 있었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;아시타카 전기&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;모노노케 히메 OST &amp;middot; The Legend of Ashitaka&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;「모노노케 히메」의 세계관을 여는 듯한 곡이었습니다. 웅장하지만 단순히 크기만 한 음악이 아니라, 운명을 향해 걸어가는 인물의 무게가 느껴졌습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;모노노케 히메&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;Princess Mononoke&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;이 곡은 공연장에서 직접 들었을 때의 공기가 달랐습니다. 맑고 높은 음색이 대강당 위로 올라가면서 숲과 신화의 이미지가 한꺼번에 떠올랐습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_program2&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;PROGRAM REVIEW&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;2부 프로그램 감상&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_program_block&quot;&gt;
&lt;h3 class=&quot;gibree_part_title&quot; data-ke-size=&quot;size23&quot;&gt;2부&lt;/h3&gt;
&lt;div class=&quot;gibree_song_list&quot;&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;언제나 몇 번이라도&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;센과 치히로의 행방불명 OST &amp;middot; Always with Me&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;이 곡은 공연의 하이라이트 중 하나였습니다. 키무라 유미님의 목소리로 직접 들으니 영화의 마지막 여운이 다시 살아나는 느낌이었습니다. 오래전 보았던 장면들이 노래와 함께 천천히 되살아났습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;생명의 이름&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;센과 치히로의 행방불명 OST &amp;middot; The Name of Life&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;「생명의 이름」은 제목 그대로 존재의 감각을 건드리는 곡이었습니다. 잔잔하지만 깊고, 조용하지만 쉽게 사라지지 않는 울림이 있었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;지구본&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;그대들은 어떻게 살 것인가 OST &amp;middot; Spinning Globe&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;비교적 최근 지브리 작품의 곡이라 앞선 명곡들과는 결이 조금 다르게 느껴졌습니다. 오래된 기억과 새로운 시간이 한 공연 안에서 이어지는 점이 좋았습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;바람이 되다&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;고양이의 보은 OST &amp;middot; Become the Wind&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;제목처럼 가볍게 바람을 타는 느낌의 곡이었습니다. 공연 분위기가 조금 더 산뜻해졌고, 지브리 특유의 따뜻한 일상감이 살아났습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;바람계곡의 나우시카&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;Nausica&amp;auml; of the Valley of the Wind&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;나우시카는 지브리의 시작을 이야기할 때 빼놓기 어려운 작품입니다. 시마모토 스미님의 존재감과 함께 들으니 단순한 OST가 아니라 한 시대의 상징처럼 느껴졌습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;바람이 지나가는 길 / 고양이 버스&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;이웃집 토토로 OST &amp;middot; The Path of the Wind / Catbus&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;토토로의 세계는 언제 들어도 마음이 부드러워집니다. 「바람이 지나가는 길」은 몽환적이고, 「고양이 버스」는 장난스럽고 귀여웠습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_song_card&quot;&gt;
&lt;h3 class=&quot;gibree_song_title&quot; data-ke-size=&quot;size23&quot;&gt;이웃집 토토로&lt;/h3&gt;
&lt;p class=&quot;gibree_song_meta&quot; data-ke-size=&quot;size16&quot;&gt;My Neighbor Totoro&lt;/p&gt;
&lt;p class=&quot;gibree_song_desc&quot; data-ke-size=&quot;size16&quot;&gt;마지막에 어울리는 곡이었습니다. 어린 시절을 지나온 사람도, 지금 처음 지브리를 접하는 사람도 함께 웃을 수 있는 곡이었습니다. 공연장을 나설 때까지 가장 오래 남은 감정은 결국 이 따뜻함이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_stage&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;STAGE DIRECTION&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;무대 연출에서 살짝 아쉬웠던 부분&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_stage_box&quot;&gt;
&lt;h3 class=&quot;gibree_stage_title&quot; data-ke-size=&quot;size23&quot;&gt;배경 스크린 연출에 대한 아쉬움&lt;/h3&gt;
&lt;p class=&quot;gibree_stage_text&quot; data-ke-size=&quot;size16&quot;&gt;공연 자체는 정말 좋았지만, 개인적으로는 뒤쪽 배경 스크린 연출이 조금 아쉽게 느껴졌습니다. 오케스트라 연주자들을 소개하거나 곡의 분위기를 보여주는 장면에서 사진이나 이미지가 나왔는데, 일부 이미지는 실제 지브리 작품의 공식 이미지라기보다는 약간 AI로 만든 듯한 지브리풍 이미지처럼 느껴졌습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_stage_text&quot; data-ke-size=&quot;size16&quot;&gt;물론 실제 제작 방식은 제가 알 수 없고, 어디까지나 관객 입장에서 받은 인상입니다. 잠깐은 &amp;ldquo;혹시 실제 지브리에서 이런 공연용 이미지를 따로 그려줄 가능성도 있으려나?&amp;rdquo;라는 생각도 했습니다. 하지만 전체적인 느낌으로는 공식 지브리 작화라기보다는 공연 분위기에 맞춰 별도로 제작한 이미지에 가까워 보였습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_stage_text&quot; data-ke-size=&quot;size16&quot;&gt;지브리 음악은 이미 작품의 이미지가 워낙 강하기 때문에, 배경 화면의 완성도나 질감이 조금만 달라도 관객 입장에서는 바로 느껴지는 것 같습니다. 차라리 공식 이미지나 작품의 분위기를 직접적으로 해치지 않는 추상적인 조명, 숲과 하늘, 바람 같은 감각적인 영상 연출이었다면 더 자연스럽게 어울렸을 것 같다는 생각이 들었습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_stage_point&quot;&gt;개인적으로는 배경 스크린이 공연의 감정을 더 깊게 만들어주는 역할을 하기보다는, 몇몇 순간에는 오히려 살짝 몰입을 깨는 느낌이 있었습니다. 공연의 음악과 출연진이 워낙 좋았기 때문에 이 부분이 더 아쉽게 느껴졌습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_stage_box&quot;&gt;
&lt;h3 class=&quot;gibree_stage_title&quot; data-ke-size=&quot;size23&quot;&gt;자막 동시 송출이 있었다면 더 좋았을 부분&lt;/h3&gt;
&lt;p class=&quot;gibree_stage_text&quot; data-ke-size=&quot;size16&quot;&gt;또 하나 아쉬웠던 점은 뒷배경 스크린에 자막이 함께 송출되었다면 훨씬 좋았을 것 같다는 점입니다. 이번 공연은 일본어 노래와 인터뷰가 중심이었기 때문에, 관객 입장에서는 가사의 의미나 출연진의 이야기를 조금 더 실시간으로 따라가고 싶은 마음이 있었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_stage_text&quot; data-ke-size=&quot;size16&quot;&gt;특히 「언제나 몇 번이라도」나 「생명의 이름」처럼 가사의 여운이 큰 곡들은 자막이 있었다면 관객들이 더 깊게 몰입할 수 있었을 것 같습니다. 음악을 들으며 동시에 가사의 의미를 따라갈 수 있었다면, 단순한 감상이 아니라 작품의 메시지를 다시 읽는 경험이 되었을 것 같습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_stage_point&quot;&gt;다음 공연이 열린다면 배경 스크린에는 분위기용 이미지보다 곡명, 작품명, 가사 자막, 인터뷰 핵심 번역이 함께 나오는 방식이 더 좋을 것 같다고 느꼈습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_photo&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;PHOTO TIME&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;공연 마지막에 남긴 장면들&lt;/h2&gt;
&lt;/div&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;공연 마지막에는 포토타임이 있었습니다. 공연 중에는 당연히 감상에 집중해야 했지만, 마지막에 이렇게 무대의 모습을 사진으로 남길 수 있는 시간이 있어 좋았습니다. 객석에서 바라본 무대는 생각보다 더 따뜻하게 느껴졌고, 노래가 끝난 뒤에도 박수와 여운이 오래 남아 있었습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/du1k5T/dJMcagFPnZR/YAIR4knJFIAMnBtyzSDwg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/du1k5T/dJMcagFPnZR/YAIR4knJFIAMnBtyzSDwg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/du1k5T/dJMcagFPnZR/YAIR4knJFIAMnBtyzSDwg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdu1k5T%2FdJMcagFPnZR%2FYAIR4knJFIAMnBtyzSDwg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;공연 마지막 무대&lt;/b&gt; 공연이 끝나갈 무렵의 무대 모습입니다. 음악이 끝난 뒤에도 객석의 분위기가 쉽게 가라앉지 않았습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FGi3G/dJMcagTkpRK/uKqnaFKKusjlnI9hC1Z3nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FGi3G/dJMcagTkpRK/uKqnaFKKusjlnI9hC1Z3nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FGi3G/dJMcagTkpRK/uKqnaFKKusjlnI9hC1Z3nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFGi3G%2FdJMcagTkpRK%2FuKqnaFKKusjlnI9hC1Z3nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;포토타임의 따뜻한 순간&lt;/b&gt; 마지막에 관객들에게 포토타임을 주는 모습입니다. 무대 위 출연진과 관객 사이의 거리가 조금 더 가까워진 느낌이었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zR73b/dJMcaf08CgN/xPWpI3To3oXkm8Jc6b1zpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zR73b/dJMcaf08CgN/xPWpI3To3oXkm8Jc6b1zpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zR73b/dJMcaf08CgN/xPWpI3To3oXkm8Jc6b1zpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzR73b%2FdJMcaf08CgN%2FxPWpI3To3oXkm8Jc6b1zpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gibree_caption&quot;&gt;&lt;b&gt;공연이 끝난 뒤 남은 여운&lt;/b&gt; 사진으로는 다 담기 어렵지만, 이 순간의 분위기는 공연의 마지막 여운을 오래 기억하게 만들어주었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;REVIEW NOTE&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;좋았던 점과 아쉬웠던 점&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_review_grid&quot;&gt;
&lt;div class=&quot;gibree_review_card gibree_review_card_blue&quot;&gt;
&lt;h3 class=&quot;gibree_review_card_title&quot; data-ke-size=&quot;size23&quot;&gt;좋았던 점&lt;/h3&gt;
&lt;p class=&quot;gibree_review_card_text&quot; data-ke-size=&quot;size16&quot;&gt;가장 좋았던 점은 오리지널 가수들의 목소리를 직접 들을 수 있었다는 점입니다. 음원으로 듣던 곡과 라이브는 확실히 달랐습니다. 숨소리, 말투, 곡 사이의 짧은 침묵까지 공연의 일부처럼 느껴졌습니다. 지브리 음악을 좋아하는 사람이라면 쉽게 잊기 어려운 경험이었을 것입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_review_card&quot;&gt;
&lt;h3 class=&quot;gibree_review_card_title&quot; data-ke-size=&quot;size23&quot;&gt;조금 아쉬웠던 점&lt;/h3&gt;
&lt;p class=&quot;gibree_review_card_text&quot; data-ke-size=&quot;size16&quot;&gt;인터뷰가 많아 가수분들의 이야기를 들을 수 있었던 점은 좋았습니다. 다만 사람에 따라서는 음악의 몰입이 중간중간 끊긴다고 느낄 수도 있을 것 같습니다. 또한 배경 스크린 이미지 일부가 약간 AI풍으로 느껴진 점과, 한국어 자막 동시 송출이 없었던 점은 개인적으로 아쉬웠습니다. 그래도 전체적으로는 음악과 출연진의 힘이 훨씬 크게 남은 공연이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;PERSONAL NOTE&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;마음에 남은 소감&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_emotion_box&quot;&gt;
&lt;h3 class=&quot;gibree_emotion_title&quot; data-ke-size=&quot;size23&quot;&gt;노래가 장면을 다시 데려오는 순간&lt;/h3&gt;
&lt;p class=&quot;gibree_emotion_text&quot; data-ke-size=&quot;size16&quot;&gt;지브리 음악의 특별함은 단순히 멜로디가 아름답다는 데에만 있지 않다고 생각합니다. 이상하게도 지브리의 노래는 듣는 순간 장면이 먼저 떠오릅니다. 하늘을 나는 성, 숲속을 걷는 아이들, 빗소리와 함께 서 있던 버스 정류장, 낯선 세계에서 다시 자신의 이름을 찾아가는 치히로의 얼굴까지, 음악은 오래전에 보았던 장면들을 아주 조용히 다시 데려옵니다.&lt;/p&gt;
&lt;p class=&quot;gibree_emotion_text&quot; data-ke-size=&quot;size16&quot;&gt;이번 공연은 바로 그런 시간이었습니다. 이미 알고 있다고 생각했던 노래들이었지만, 오리지널 싱어즈의 목소리로 직접 들으니 전혀 다르게 다가왔습니다. 음원으로 들을 때는 지나쳤던 떨림과 호흡, 한 소절이 끝난 뒤 남는 공기까지 느껴졌습니다. 그래서 공연을 보는 동안에는 단순히 노래를 감상한다기보다, 제가 좋아했던 작품들과 다시 한 번 조용히 마주 앉아 있는 기분이 들었습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_emotion_text&quot; data-ke-size=&quot;size16&quot;&gt;특히 출연진이 서툰 한국어로라도 관객에게 말을 건네려는 모습이 오래 기억에 남습니다. 완벽하지 않아서 더 진심처럼 느껴졌고, 그 마음이 객석까지 부드럽게 전해졌습니다. 좋은 공연은 노래를 잘하는 것만으로 완성되는 것이 아니라, 무대 위 사람과 객석의 마음이 같은 방향을 바라볼 때 만들어진다는 것을 느꼈습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gibree_section_epilogue&quot; class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;EPILOGUE&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;마무리 후기&lt;/h2&gt;
&lt;/div&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;이번 공연은 단순한 OST 콘서트라기보다, 지브리 음악을 만든 시간과 그 노래를 불러온 사람들을 직접 만나는 자리였습니다. 영화 속에서 흘러나오던 노래를 실제 목소리로 듣는다는 것은 생각보다 훨씬 특별한 경험이었습니다. 노래 한 곡이 끝날 때마다 박수만 남는 것이 아니라, 각자의 마음속에 있던 장면과 기억이 함께 흔들리는 듯했습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;지브리 작품은 어린 시절의 추억처럼 느껴지기도 하고, 어른이 된 뒤 다시 보면 또 다른 의미로 다가오기도 합니다. 그래서 이번 공연은 단순히 과거를 추억하는 시간이 아니라, 지금의 제가 다시 지브리 음악을 받아들이는 시간이기도 했습니다. 예전에는 멜로디가 좋아서 들었던 곡들이 이제는 위로처럼 들렸고, 장면을 떠올리게 하던 노래들이 어느 순간 제 자신의 기억과도 겹쳐졌습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;물론 아쉬움이 전혀 없었던 것은 아닙니다. 배경 스크린의 이미지 연출은 조금 더 세심했으면 좋았겠다는 생각이 들었고, 한국어 자막이 함께 나왔다면 노래의 감정과 인터뷰의 의미가 관객들에게 더 깊게 전달되었을 것 같습니다. 하지만 그런 아쉬움에도 불구하고, 공연의 중심에 있던 목소리와 음악의 힘은 충분히 강했습니다.&lt;/p&gt;
&lt;div class=&quot;gibree_final_box&quot;&gt;
&lt;h3 class=&quot;gibree_final_title&quot; data-ke-size=&quot;size23&quot;&gt;최종 감상&lt;/h3&gt;
&lt;p class=&quot;gibree_final_text&quot; data-ke-size=&quot;size16&quot;&gt;공연장을 나설 때는 큰 감동이 한꺼번에 밀려왔다기보다, 은은한 여운이 천천히 따라오는 느낌이었습니다. 연세대학교 대강당의 공기, 무대 위 조명, 오케스트라의 잔향, 출연진의 서툴지만 따뜻했던 한국어 인사, 그리고 유유님의 귀여운 말투와 밝은 리액션까지 모두 오래 기억에 남을 것 같습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_final_text&quot; data-ke-size=&quot;size16&quot;&gt;초대권 이벤트 당첨으로 보게 된 공연이었지만, 공연이 끝난 뒤에는 오히려 &amp;ldquo;예매해서라도 꼭 봤어야 할 공연이었다&amp;rdquo;는 생각이 들었습니다. 결국 이 공연을 가장 잘 표현하는 말은 &lt;b&gt;귀가 호강한 시간&lt;/b&gt;입니다. 하지만 그 말만으로는 조금 부족합니다. 이번 공연은 귀로 들었지만 마음으로 오래 남는 시간이었고, 익숙한 노래를 통해 잊고 있던 감정을 다시 꺼내보게 해준 시간이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;gibree_section gibree_reveal&quot;&gt;
&lt;div class=&quot;gibree_section_head&quot;&gt;&lt;span class=&quot;gibree_section_kicker&quot;&gt;SEO FAQ&lt;/span&gt;
&lt;h2 class=&quot;gibree_section_title&quot; data-ke-size=&quot;size26&quot;&gt;공연 후기 요약 FAQ&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;gibree_faq_box&quot;&gt;
&lt;h3 class=&quot;gibree_faq_title&quot; data-ke-size=&quot;size23&quot;&gt;스튜디오 지브리 오리지널 싱어즈 공연은 어땠나요?&lt;/h3&gt;
&lt;p class=&quot;gibree_faq_text&quot; data-ke-size=&quot;size16&quot;&gt;지브리 OST를 원곡 가수들의 목소리와 오케스트라 연주로 들을 수 있다는 점에서 매우 특별했습니다. 단순한 OST 콘서트가 아니라, 지브리 작품의 장면과 감정을 다시 꺼내보는 공연에 가까웠습니다.&lt;/p&gt;
&lt;h3 class=&quot;gibree_faq_title&quot; data-ke-size=&quot;size23&quot;&gt;가장 인상 깊었던 무대는 무엇이었나요?&lt;/h3&gt;
&lt;p class=&quot;gibree_faq_text&quot; data-ke-size=&quot;size16&quot;&gt;키무라 유미님의 「언제나 몇 번이라도」, 이노우에 아즈미님의 토토로와 라퓨타 관련 곡, 요네라 요시카즈님의 「모노노케 히메」가 특히 인상 깊었습니다. 시마모토 스미님의 더빙 시연도 공연 전체에서 오래 기억에 남는 순간이었습니다.&lt;/p&gt;
&lt;h3 class=&quot;gibree_faq_title&quot; data-ke-size=&quot;size23&quot;&gt;아쉬운 점은 있었나요?&lt;/h3&gt;
&lt;p class=&quot;gibree_faq_text&quot; data-ke-size=&quot;size16&quot;&gt;무대 뒤 배경 스크린 이미지 일부가 약간 AI풍으로 느껴진 점과, 한국어 자막이 동시 송출되지 않았던 점은 아쉬웠습니다. 다만 음악과 출연진의 진정성이 훨씬 크게 남은 공연이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;footer class=&quot;gibree_footer_note gibree_reveal&quot;&gt;
&lt;h2 class=&quot;gibree_footer_note_title&quot; data-ke-size=&quot;size26&quot;&gt;참고 및 기록&lt;/h2&gt;
&lt;p class=&quot;gibree_footer_note_text&quot; data-ke-size=&quot;size16&quot;&gt;공연 정보와 프로그램은 공식 예매 페이지 및 공연 상세 이미지를 참고했으며, 관람 후기는 직접 관람한 경험을 바탕으로 작성했습니다.&lt;/p&gt;
&lt;p class=&quot;gibree_footer_note_text&quot; data-ke-size=&quot;size16&quot;&gt;공식 공연 페이지 : &lt;a href=&quot;https://tickets.interpark.com/goods/26006719&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; 스튜디오 지브리 오리지널 싱어즈 첫 내한 공연 &lt;/a&gt;&lt;/p&gt;
&lt;/footer&gt;&lt;/article&gt;
&lt;script&gt;
  (function gibree_initReveal() {
    var gibree_items = document.querySelectorAll(&quot;.gibree_reveal&quot;);

    if (!(&quot;IntersectionObserver&quot; in window)) {
      gibree_items.forEach(function (gibree_item) {
        gibree_item.classList.add(&quot;gibree_is_visible&quot;);
      });
      return;
    }

    var gibree_observer = new IntersectionObserver(function (gibree_entries) {
      gibree_entries.forEach(function (gibree_entry) {
        if (gibree_entry.isIntersecting) {
          gibree_entry.target.classList.add(&quot;gibree_is_visible&quot;);
          gibree_observer.unobserve(gibree_entry.target);
        }
      });
    }, {
      threshold: 0.12
    });

    gibree_items.forEach(function (gibree_item) {
      gibree_observer.observe(gibree_item);
    });
  })();
&lt;/script&gt;</description>
      <category>DailyRoutine</category>
      <category>센과치히로의행방불명</category>
      <category>스튜디오지브리</category>
      <category>시마모토스미</category>
      <category>음악</category>
      <category>이노우에아즈미</category>
      <category>이웃집토토로</category>
      <category>지브리공연후기</category>
      <category>지브리콘서트</category>
      <category>천공의성라퓨타</category>
      <category>키무라유미</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/589</guid>
      <comments>https://odinbox.tistory.com/589#entry589comment</comments>
      <pubDate>Mon, 8 Jun 2026 06:05:12 +0900</pubDate>
    </item>
    <item>
      <title>국민투자펀드 총정리, 국민참여형 국민성장펀드 구조&amp;middot;세제혜택&amp;middot;가입방법&amp;middot;위험요인</title>
      <link>https://odinbox.tistory.com/588</link>
      <description>&lt;div class=&quot;gov-light-post&quot;&gt;
&lt;style&gt;
  .gov-light-post {
    --gov-bg: #ffffff;
    --gov-surface: #ffffff;
    --gov-surface-soft: #f7f9fc;
    --gov-surface-muted: #eef3f8;
    --gov-surface-blue: #f4f8fd;
    --gov-text: #1f2937;
    --gov-text-strong: #111827;
    --gov-text-muted: #667085;
    --gov-border: #d0d7de;
    --gov-border-soft: #e5e7eb;
    --gov-primary: #003764;
    --gov-primary-deep: #002b4f;
    --gov-primary-soft: #eaf3ff;
    --gov-warning-bg: #fff8ed;
    --gov-warning-border: #d97706;
    --gov-warning-text: #92400e;
    --gov-link: #004f9f;

    color-scheme: light;
    font-family: &quot;Noto Sans KR&quot;, &quot;Malgun Gothic&quot;, Apple SD Gothic Neo, Arial, sans-serif !important;
    color: var(--gov-text) !important;
    line-height: 1.85 !important;
    word-break: keep-all;
    max-width: 920px;
    margin: 0 auto;
    background: var(--gov-bg) !important;
  }

  .gov-light-post * {
    box-sizing: border-box;
  }

  .gov-light-post,
  .gov-light-post article,
  .gov-light-post div,
  .gov-light-post section,
  .gov-light-post nav,
  .gov-light-post header,
  .gov-light-post p,
  .gov-light-post table,
  .gov-light-post th,
  .gov-light-post td {
    color: inherit;
  }

  .gov-light-post .gov-doc {
    border: 1px solid var(--gov-border) !important;
    background: var(--gov-surface) !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-top-line {
    height: 8px;
    background: var(--gov-primary) !important;
  }

  .gov-light-post .gov-header {
    padding: 30px 32px 26px;
    border-bottom: 2px solid var(--gov-primary-deep) !important;
    background: #ffffff !important;
  }

  .gov-light-post .gov-kicker {
    display: inline-block;
    padding: 6px 12px;
    margin-bottom: 16px;
    border: 1px solid #8bb8e8 !important;
    color: var(--gov-primary) !important;
    font-size: 0.86rem;
    font-weight: 700;
    background: #f7fbff !important;
  }

  .gov-light-post .gov-title {
    margin: 0;
    font-size: 1.95rem;
    line-height: 1.38;
    letter-spacing: -0.04em;
    color: var(--gov-text-strong) !important;
    font-weight: 800;
  }

  .gov-light-post .gov-subtitle {
    margin: 14px 0 0;
    color: var(--gov-text-muted) !important;
    font-size: 1rem;
  }

  .gov-light-post .gov-thumbnail {
    margin: 26px 0 24px;
    text-align: center;
    background: #ffffff !important;
  }

  .gov-light-post .gov-thumbnail p {
    margin: 0 !important;
    text-align: center !important;
  }

  .gov-light-post .gov-thumbnail img {
    display: block;
    max-width: 420px;
    width: 100%;
    height: auto;
    margin: 0 auto;
    border-radius: 10px;
  }

  .gov-light-post .gov-meta {
    margin-top: 22px;
    border-top: 1px solid var(--gov-border) !important;
    border-bottom: 1px solid var(--gov-border) !important;
    background: #ffffff !important;
  }

  .gov-light-post .gov-meta table {
    width: 100%;
    border-collapse: collapse;
    margin: 0;
    font-size: 0.94rem;
    background: #ffffff !important;
  }

  .gov-light-post .gov-meta th {
    width: 132px;
    padding: 10px 12px;
    border-right: 1px solid var(--gov-border) !important;
    border-bottom: 1px solid var(--gov-border-soft) !important;
    background: #eef3f8 !important;
    color: var(--gov-text-strong) !important;
    text-align: left;
    font-weight: 700;
  }

  .gov-light-post .gov-meta td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--gov-border-soft) !important;
    background: #ffffff !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-body {
    padding: 32px;
    background: #ffffff !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-notice {
    margin: 26px 0;
    border: 1px solid #8bb8e8 !important;
    border-top: 4px solid var(--gov-primary) !important;
    background: #f7fbff !important;
  }

  .gov-light-post .gov-notice-title {
    padding: 12px 16px;
    background: #f0f6fd !important;
    border-bottom: 1px solid #c9def5 !important;
    color: var(--gov-primary-deep) !important;
    font-weight: 800;
  }

  .gov-light-post .gov-notice-content {
    padding: 16px 18px;
    background: #ffffff !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-notice-content p {
    margin: 8px 0;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-summary-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin: 20px 0;
  }

  .gov-light-post .gov-summary-card {
    border: 1px solid var(--gov-border) !important;
    background: #ffffff !important;
    padding: 15px;
  }

  .gov-light-post .gov-summary-card strong {
    display: block;
    color: var(--gov-primary-deep) !important;
    margin-bottom: 5px;
    font-size: 0.94rem;
  }

  .gov-light-post .gov-summary-card span {
    display: block;
    color: var(--gov-text-strong) !important;
    font-size: 0.98rem;
  }

  .gov-light-post .gov-toc {
    margin: 28px 0;
    padding: 18px 20px;
    border: 1px solid var(--gov-border) !important;
    background: #f8fafc !important;
  }

  .gov-light-post .gov-toc strong {
    display: block;
    margin-bottom: 8px;
    color: var(--gov-primary-deep) !important;
    font-size: 1.05rem;
  }

  .gov-light-post .gov-toc ol {
    margin: 0;
    padding-left: 22px;
  }

  .gov-light-post .gov-toc li {
    margin: 5px 0;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-toc a {
    color: var(--gov-text-strong) !important;
    text-decoration: none !important;
  }

  .gov-light-post .gov-toc a:hover {
    color: var(--gov-link) !important;
    text-decoration: underline !important;
    text-underline-offset: 3px;
  }

  .gov-light-post .gov-section {
    margin-top: 44px;
    background: #ffffff !important;
  }

  .gov-light-post .gov-section h2 {
    margin: 0 0 18px;
    padding: 13px 15px;
    border-left: 6px solid var(--gov-primary) !important;
    border-bottom: 1px solid var(--gov-border) !important;
    background: #eef3f8 !important;
    color: var(--gov-text-strong) !important;
    font-size: 1.35rem;
    letter-spacing: -0.03em;
    font-weight: 800;
  }

  .gov-light-post .gov-section h3 {
    margin: 28px 0 12px;
    padding-left: 10px;
    border-left: 4px solid #8a98a8 !important;
    color: var(--gov-text-strong) !important;
    font-size: 1.12rem;
    font-weight: 800;
  }

  .gov-light-post .gov-section p {
    margin: 13px 0;
    color: var(--gov-text) !important;
  }

  .gov-light-post strong {
    color: var(--gov-text-strong) !important;
    font-weight: 800;
  }

  .gov-light-post .gov-table-wrap {
    width: 100%;
    overflow-x: auto;
    margin: 18px 0;
  }

  .gov-light-post .gov-table {
    width: 100%;
    min-width: 640px;
    border-collapse: collapse;
    margin: 0;
    font-size: 0.94rem;
    border-top: 2px solid var(--gov-primary-deep) !important;
    background: #ffffff !important;
  }

  .gov-light-post .gov-table th {
    padding: 11px 10px;
    border: 1px solid var(--gov-border) !important;
    background: #eef3f8 !important;
    color: var(--gov-text-strong) !important;
    text-align: left;
    font-weight: 800;
  }

  .gov-light-post .gov-table td {
    padding: 11px 10px;
    border: 1px solid var(--gov-border-soft) !important;
    vertical-align: top;
    background: #ffffff !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-table caption {
    caption-side: top;
    text-align: left;
    font-weight: 800;
    color: var(--gov-primary-deep) !important;
    margin-bottom: 8px;
  }

  .gov-light-post .gov-warning {
    margin: 22px 0;
    padding: 16px 18px;
    border: 1px solid var(--gov-warning-border) !important;
    border-left: 6px solid var(--gov-warning-border) !important;
    background: var(--gov-warning-bg) !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-warning strong {
    color: var(--gov-warning-text) !important;
  }

  .gov-light-post .gov-info {
    margin: 22px 0;
    padding: 16px 18px;
    border: 1px solid #b7d1ec !important;
    border-left: 6px solid var(--gov-primary) !important;
    background: #f7fbff !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-source-box {
    margin-top: 28px;
    padding: 18px;
    border: 1px solid var(--gov-border) !important;
    background: #f8fafc !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-source-box ul {
    margin: 10px 0 0;
    padding-left: 20px;
  }

  .gov-light-post .gov-source-box li {
    margin: 7px 0;
    color: var(--gov-text) !important;
  }

  .gov-light-post a {
    color: var(--gov-link) !important;
    text-decoration: underline !important;
    text-underline-offset: 3px;
  }

  .gov-light-post .gov-tags {
    margin-top: 24px;
    padding: 16px;
    border-top: 2px solid var(--gov-primary-deep) !important;
    background: #f8fafc !important;
    color: var(--gov-text) !important;
  }

  .gov-light-post .gov-tags strong {
    color: var(--gov-text-strong) !important;
  }

  .gov-light-post .gov-tags span {
    display: inline-block;
    margin: 4px 5px 4px 0;
    padding: 5px 9px;
    border: 1px solid var(--gov-border) !important;
    background: #ffffff !important;
    color: var(--gov-text) !important;
    font-size: 0.88rem;
  }

  .gov-light-post .gov-disclaimer {
    margin-top: 28px;
    padding: 15px;
    border: 1px solid var(--gov-border) !important;
    background: #ffffff !important;
    color: var(--gov-text-muted) !important;
    font-size: 0.9rem;
  }

  @media (max-width: 720px) {
    .gov-light-post .gov-header,
    .gov-light-post .gov-body {
      padding: 22px 18px;
    }

    .gov-light-post .gov-title {
      font-size: 1.55rem;
    }

    .gov-light-post .gov-summary-grid {
      grid-template-columns: 1fr;
    }

    .gov-light-post .gov-meta th {
      width: 104px;
    }

    .gov-light-post .gov-table {
      font-size: 0.88rem;
    }
  }
&lt;/style&gt;
&lt;article class=&quot;gov-doc&quot;&gt;
&lt;div class=&quot;gov-top-line&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;header class=&quot;gov-header&quot;&gt;
&lt;div class=&quot;gov-kicker&quot;&gt;정책자료 정리&lt;/div&gt;
&lt;p class=&quot;gov-subtitle&quot; data-ke-size=&quot;size16&quot;&gt;정부 공식 발표자료를 바탕으로 국민투자펀드로 불리는 국민참여형 국민성장펀드의 핵심 내용을 정리했습니다!&lt;/p&gt;
&lt;div class=&quot;gov-thumbnail&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2X9ul/dJMcajh6C7E/S2tpj23TKYKxmo3QDCGUoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2X9ul/dJMcajh6C7E/S2tpj23TKYKxmo3QDCGUoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2X9ul/dJMcajh6C7E/S2tpj23TKYKxmo3QDCGUoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2X9ul%2FdJMcajh6C7E%2FS2tpj23TKYKxmo3QDCGUoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;div class=&quot;gov-body&quot;&gt;
&lt;div class=&quot;gov-notice&quot;&gt;
&lt;div class=&quot;gov-notice-title&quot;&gt;핵심 요약&lt;/div&gt;
&lt;div class=&quot;gov-notice-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 검색되는 &lt;b&gt;국민투자펀드&lt;/b&gt;는 정부 공식 명칭으로는 &lt;b&gt;국민참여형 국민성장펀드&lt;/b&gt;에 해당합니다. 이는 정부가 발표한 150조 원 규모 국민성장펀드 정책 중 일반 국민이 공모펀드 형태로 참여할 수 있도록 설계된 상품입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년형 상품은 국민 투자금 &lt;b&gt;6,000억 원&lt;/b&gt;과 재정 후순위 자금 &lt;b&gt;1,200억 원&lt;/b&gt;을 결합한 구조이며, 첨단전략산업과 관련 기업에 장기 자금을 공급하는 것을 목적으로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 이 상품은 &lt;b&gt;원금보장 상품이 아니며&lt;/b&gt;, 5년 만기 환매금지형 구조라는 점을 반드시 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gov-summary-grid&quot;&gt;
&lt;div class=&quot;gov-summary-card&quot;&gt;&lt;b&gt;정책 규모&lt;/b&gt; &lt;span&gt;국민성장펀드 총 150조 원 규모&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gov-summary-card&quot;&gt;&lt;b&gt;국민참여형 규모&lt;/b&gt; &lt;span&gt;국민 투자금 6,000억 원 + 재정 후순위 1,200억 원&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gov-summary-card&quot;&gt;&lt;b&gt;주요 투자분야&lt;/b&gt; &lt;span&gt;반도체, AI, 바이오, 이차전지, 로봇, 방산, 미래차 등&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gov-summary-card&quot;&gt;&lt;b&gt;핵심 유의사항&lt;/b&gt; &lt;span&gt;원금보장 아님, 5년 만기 환매금지형&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;nav class=&quot;gov-toc&quot;&gt;&lt;b&gt;목차&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#sec01&quot;&gt;국민투자펀드란 무엇인가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec02&quot;&gt;정부가 발표한 배경과 목적&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec03&quot;&gt;펀드 구조와 운용 방식&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec04&quot;&gt;세제혜택과 가입 조건&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec05&quot;&gt;출시 일정과 판매 현황&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec06&quot;&gt;투자 전 반드시 확인할 위험요인&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec07&quot;&gt;자주 묻는 질문&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec08&quot;&gt;마무리&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/nav&gt;
&lt;section id=&quot;sec01&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 국민투자펀드란 무엇인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국민투자펀드라는 표현은 언론, 커뮤니티, 검색어에서 많이 사용되고 있지만, 정부 공식 자료에서 중심적으로 사용되는 명칭은 &lt;b&gt;국민성장펀드&lt;/b&gt;입니다. 그중 일반 국민이 직접 공모펀드 형태로 참여할 수 있도록 만든 상품이 &lt;b&gt;국민참여형 국민성장펀드&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 일반 투자자가 공모펀드에 가입하면 해당 자금이 여러 자펀드로 나뉘어 첨단전략산업 관련 기업에 투자되는 구조입니다. 개인이 직접 비상장 기업이나 첨단산업 기업에 투자하기는 어렵기 때문에, 정부는 공모펀드와 자펀드 구조를 통해 국민 참여 통로를 만든 것입니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;공식 명칭과 일반 검색어 구분&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;정부 공식 사업명&lt;/th&gt;
&lt;td&gt;국민성장펀드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;일반 국민 대상 상품명&lt;/th&gt;
&lt;td&gt;국민참여형 국민성장펀드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;검색상 자주 쓰이는 표현&lt;/th&gt;
&lt;td&gt;국민투자펀드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;상품 성격&lt;/th&gt;
&lt;td&gt;원금보장형 예금이 아닌 실적배당형 펀드&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sec02&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 정부가 발표한 배경과 목적&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정부는 2025년 9월, 향후 5년간 &lt;b&gt;150조 원 규모의 국민성장펀드&lt;/b&gt;를 조성하겠다고 발표했습니다. 이 펀드는 단순히 하나의 금융상품을 만드는 것이 아니라, 첨단전략산업에 장기 자금을 공급해 한국 경제의 미래 성장동력을 확보하겠다는 정책금융 프로젝트입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;150조 원은 크게 &lt;b&gt;첨단전략산업기금 75조 원&lt;/b&gt;과 &lt;b&gt;민간&amp;middot;국민&amp;middot;금융권 자금 75조 원&lt;/b&gt;으로 구성됩니다. 국민참여형 국민성장펀드는 이 중 일반 국민이 체감할 수 있는 참여형 상품으로 이해할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gov-info&quot;&gt;&lt;b&gt;정책 목적 요약&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부동산&amp;middot;담보 중심으로 쏠려 있던 시중 자금을 첨단산업, 혁신기업, 생산적 금융으로 유도하고, 국민이 성장산업 투자 성과에 일부 참여할 수 있도록 하는 것이 핵심 취지입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sec03&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 펀드 구조와 운용 방식&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 기본 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년형 국민참여형 국민성장펀드는 국민 투자금 &lt;b&gt;6,000억 원&lt;/b&gt;과 재정 후순위 자금 &lt;b&gt;1,200억 원&lt;/b&gt;을 결합한 구조입니다. 여기에 자펀드 운용사의 후순위 시딩투자금도 추가됩니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;국민참여형 국민성장펀드 구성&lt;/caption&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구성 요소&lt;/th&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;국민 투자금&lt;/td&gt;
&lt;td&gt;6,000억 원&lt;/td&gt;
&lt;td&gt;일반 국민이 공모펀드를 통해 투자하는 선순위 자금&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;재정 후순위 자금&lt;/td&gt;
&lt;td&gt;1,200억 원&lt;/td&gt;
&lt;td&gt;손실 발생 시 국민 투자금보다 먼저 손실을 부담하는 완충 장치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;자펀드 운용사 시딩&lt;/td&gt;
&lt;td&gt;자펀드별 1~5% 수준&lt;/td&gt;
&lt;td&gt;운용사의 책임 운용을 유도하기 위한 후순위 투자금&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 공모펀드 3개, 자펀드 10개 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 투자자가 가입하는 공모펀드는 미래에셋자산운용, 삼성자산운용, KB자산운용 등 3개 운용사가 담당합니다. 이 3개 공모펀드는 최종적으로 10개 자펀드에 동일 비중으로 투자하는 구조입니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;운용사 구조&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;공모펀드 운용사&lt;/th&gt;
&lt;td&gt;미래에셋자산운용, 삼성자산운용, KB자산운용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;자펀드 운용사&lt;/th&gt;
&lt;td&gt;디에스자산운용, 미래에셋자산운용, 라이프자산운용, 마이다스에셋자산운용, 타임폴리오자산운용, 한국투자밸류자산운용, 더제이자산운용, 수성자산운용, 오라이언자산운용, KB자산운용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 주요 투자 대상&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자펀드는 결성금액의 60% 이상을 첨단전략산업 기업과 관련 기업에 투자해야 합니다. 정부 발표자료에서 언급된 주요 산업은 다음과 같습니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;주요 투자 분야&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;첨단산업&lt;/th&gt;
&lt;td&gt;반도체, 이차전지, 수소, 미래차, 바이오, 인공지능, 방산, 로봇, 콘텐츠, 핵심광물 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;관련 기업&lt;/th&gt;
&lt;td&gt;첨단 장비, 설비, 인프라, 소재, 부품, 서비스 관련 기업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;신규 자금 공급&lt;/th&gt;
&lt;td&gt;비상장기업 및 코스닥 기술특례상장사 등에 대한 신규 투자 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sec04&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 세제혜택과 가입 조건&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국민참여형 국민성장펀드가 관심을 받은 가장 큰 이유 중 하나는 세제혜택입니다. 전용계좌를 통해 가입하면 투자금액 구간에 따라 소득공제를 받을 수 있고, 배당소득에 대해서도 저율 분리과세 혜택이 적용됩니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;투자금액별 소득공제율&lt;/caption&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;3,000만 원 이하&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3,000만 원 초과 ~ 5,000만 원 이하&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5,000만 원 초과 ~ 7,000만 원 이하&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 소득공제 한도는 &lt;b&gt;1,800만 원&lt;/b&gt;입니다. 또한 배당소득은 투자일부터 5년까지 &lt;b&gt;9% 분리과세&lt;/b&gt;가 적용됩니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;가입 조건 및 한도&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;세제혜택 가능 대상&lt;/th&gt;
&lt;td&gt;19세 이상 또는 15세 이상 근로소득자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;제외 대상&lt;/th&gt;
&lt;td&gt;펀드 출시 연도 직전 3개년 중 1회라도 금융소득종합과세 대상자였던 경우 전용계좌 개설 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;전용계좌 총 투자한도&lt;/th&gt;
&lt;td&gt;5년간 2억 원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;상품 가입한도&lt;/th&gt;
&lt;td&gt;1인당 연간 1억 원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;일반계좌 가입&lt;/th&gt;
&lt;td&gt;세제혜택을 포기하면 일반계좌로도 가입 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;일반계좌 한도&lt;/th&gt;
&lt;td&gt;1인당 연간 3,000만 원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;gov-warning&quot;&gt;&lt;b&gt;유의사항&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세제혜택을 받기 위해서는 전용계좌 가입 요건을 충족해야 합니다. 실제 가입 전에는 판매사의 투자설명서, 증권신고서, 수수료, 위험등급, 세제 요건을 반드시 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sec05&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 출시 일정과 판매 현황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년형 국민참여형 국민성장펀드는 2026년 5월 22일 판매를 시작했습니다. 원래 판매 기간은 2026년 6월 11일까지로 예정되어 있었으나, 투자 수요가 몰리면서 2026년 5월 29일 오전 기준 모집금액 6,000억 원이 완판됐습니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;주요 일정&lt;/caption&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;2025년 9월 10일&lt;/td&gt;
&lt;td&gt;정부, 150조 원 규모 국민성장펀드 발표&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 3월 13일&lt;/td&gt;
&lt;td&gt;공모펀드 운용사 3곳 선정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 4월 10일&lt;/td&gt;
&lt;td&gt;자펀드 운용사 선정기준 발표&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 5월 6일&lt;/td&gt;
&lt;td&gt;자펀드 10곳 및 판매계획 발표&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 5월 22일&lt;/td&gt;
&lt;td&gt;일반 국민 대상 판매 시작&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 5월 29일&lt;/td&gt;
&lt;td&gt;6,000억 원 완판&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 6월 12일 예정&lt;/td&gt;
&lt;td&gt;펀드 설정 예정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026년 6월 15일 예정&lt;/td&gt;
&lt;td&gt;자펀드 실제 투자 개시 예정&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금융위원회 발표 기준 완판 당시 전체 가입자는 &lt;b&gt;30,258명&lt;/b&gt;, 1인당 평균 가입액은 약 &lt;b&gt;1,983만 원&lt;/b&gt;으로 집계됐습니다. 다만 취소 물량이나 추가 출시 여부는 판매사와 금융위원회 공식 공지를 통해 확인해야 합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sec06&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 투자 전 반드시 확인할 위험요인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-1. 원금보장 상품이 아닙니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재정 후순위 자금과 운용사 시딩투자금이 손실을 먼저 흡수하는 구조는 맞습니다. 하지만 이는 손실 완충 장치일 뿐, 원금을 보장하는 구조가 아닙니다. 손실이 후순위 완충 범위를 넘어가면 일반 투자자도 손실을 볼 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-2. 5년 만기 환매금지형 상품입니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상품은 5년 만기 환매금지형입니다. 중도환매가 불가능하고, 거래소 상장 후 양도는 가능할 수 있으나 유동성이 낮거나 기준가격보다 낮은 가격에 거래될 가능성이 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-3. 첨단산업과 비상장 투자 특유의 변동성이 있습니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반도체, AI, 바이오, 로봇, 방산, 이차전지 등 성장성이 높은 산업은 경기 사이클, 정책 변화, 기술 경쟁, 밸류에이션 변동에 민감합니다. 특히 비상장기업과 기술특례상장사 투자가 포함될 수 있으므로 일반 예금이나 채권형 상품보다 위험도가 높을 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gov-table-wrap&quot;&gt;
&lt;table class=&quot;gov-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;caption&gt;장점과 유의사항 비교&lt;/caption&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;소득공제와 분리과세 혜택&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;/tr&gt;
&lt;tr&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;/tr&gt;
&lt;tr&gt;
&lt;td&gt;국민 참여형 정책금융 상품&lt;/td&gt;
&lt;td&gt;5년 동안 자금이 묶일 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sec07&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 자주 묻는 질문&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q1. 국민투자펀드와 국민성장펀드는 같은 말인가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확한 공식 명칭은 국민성장펀드이며, 일반 국민이 가입할 수 있는 상품은 국민참여형 국민성장펀드입니다. 국민투자펀드는 검색과 대화에서 많이 쓰이는 비공식 표현으로 보는 것이 정확합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q2. 지금도 가입할 수 있나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 5월 31일 기준 초기 모집금액 6,000억 원은 2026년 5월 29일 오전 완판됐습니다. 다만 모집 종료 전 취소 물량이나 추가 판매 여부는 개별 판매사와 금융위원회 공식 공지를 통해 확인해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q3. 정부가 손실을 일부 부담하면 안전한 상품인가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아닙니다. 재정 후순위 자금은 손실을 일부 먼저 흡수하는 장치일 뿐입니다. 손실 규모가 완충 범위를 넘으면 일반 투자자도 손실을 볼 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q4. 세제혜택은 얼마나 받을 수 있나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투자금액 구간에 따라 3,000만 원 이하 40%, 3,000만 원 초과 5,000만 원 이하 20%, 5,000만 원 초과 7,000만 원 이하 10%의 소득공제 혜택이 적용됩니다. 최대 소득공제 한도는 1,800만 원입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q5. 어떤 사람에게 적합한가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5년 이상 묶어둘 수 있는 여유자금이 있고, 첨단산업 장기 투자와 세제혜택에 관심이 있는 투자자에게 적합할 수 있습니다. 반대로 단기 자금이 필요하거나 원금 손실을 감수하기 어려운 사람에게는 맞지 않을 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sec08&quot; class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국민투자펀드로 많이 불리는 국민참여형 국민성장펀드는 정부의 150조 원 규모 국민성장펀드 정책 중 일반 국민이 참여할 수 있도록 만든 대표 상품입니다. 첨단전략산업에 장기 자금을 공급하고, 국민도 그 성장 성과에 일부 참여할 수 있도록 설계됐다는 점에서 의미가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 좋은 취지와 세제혜택이 있다고 해서 무조건 안전한 상품은 아닙니다. 이 상품은 원금보장 상품이 아니며, 5년 환매금지형 구조이고, 첨단산업과 비상장기업 투자 특유의 변동성을 가지고 있습니다.&lt;/p&gt;
&lt;div class=&quot;gov-warning&quot;&gt;&lt;b&gt;최종 점검사항&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상품을 검토할 때는 &amp;ldquo;정부가 만든 상품인가?&amp;rdquo;보다 &amp;ldquo;내가 5년 동안 묶어둘 수 있는 여유자금으로 감당 가능한 위험인가?&amp;rdquo;를 먼저 판단해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;gov-section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료 및 출처&lt;/h2&gt;
&lt;div class=&quot;gov-source-box&quot;&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;a href=&quot;https://www.fsc.go.kr/no010101/85265&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 국민성장펀드 관련 정부 공식 보도자료&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/86156&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 국민참여형 국민성장펀드 TF 회의&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/86454&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 공모펀드 운용사 선정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/86686&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 자펀드 운용사 선정기준 발표&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/86834&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 국민참여형 국민성장펀드 판매 계획&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/86927&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 국민참여형 국민성장펀드 가입 FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/86950&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 투자구조와 우선 손실 부담 설명&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fsc.go.kr/no010101/87009&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;금융위원회: 국민참여형 국민성장펀드 완판 발표&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.moef.go.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;기획재정부: 경제정책 및 성장전략 관련 자료&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.law.go.kr/lsInfoP.do?ancYnChk=0&amp;amp;lsId=001584&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;국가법령정보센터: 조세특례제한법&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;div class=&quot;gov-tags&quot;&gt;&lt;b&gt;태그 10개&lt;/b&gt;&lt;br /&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;/div&gt;
&lt;div class=&quot;gov-disclaimer&quot;&gt;본 글은 정부 공식 발표자료와 공개 자료를 바탕으로 작성한 정보성 콘텐츠입니다. 특정 금융상품의 가입을 권유하는 글이 아니며, 실제 투자 여부는 투자설명서와 판매사 안내를 확인한 뒤 본인의 판단에 따라 결정해야 합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine/Economy</category>
      <category>국민성장펀드</category>
      <category>국민성장펀드가입방법</category>
      <category>국민성장펀드세제혜택</category>
      <category>국민성장펀드수익률</category>
      <category>국민성장펀드위험</category>
      <category>국민성장펀드출시일정</category>
      <category>국민참여형국민성장펀드</category>
      <category>국민투자펀드</category>
      <category>정부주도</category>
      <category>첨단전략사업펀드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/588</guid>
      <comments>https://odinbox.tistory.com/588#entry588comment</comments>
      <pubDate>Tue, 2 Jun 2026 21:21:47 +0900</pubDate>
    </item>
    <item>
      <title>ZARD(자드) 坂井泉水 5월 27일 추모 &amp;mdash; 사카이 이즈미를 기억하며</title>
      <link>https://odinbox.tistory.com/587</link>
      <description>&lt;div class=&quot;zard_memorial_wrap&quot;&gt;
&lt;style&gt;
    .zard_memorial_wrap {
      --zard-bg: #0f0e0d;
      --zard-bg2: #181310;
      --zard-card: rgba(255, 255, 255, 0.075);
      --zard-card2: rgba(255, 255, 255, 0.11);
      --zard-text: #f8f1e7;
      --zard-muted: #cfc5b8;
      --zard-soft: #eee0cc;
      --zard-gold: #d8bc76;
      --zard-gold2: #f4dc9a;
      --zard-line: rgba(216, 188, 118, 0.34);
      --zard-shadow: 0 26px 80px rgba(0, 0, 0, 0.42);

      max-width: 980px;
      margin: 0 auto;
      color: var(--zard-text);
      font-family: -apple-system, BlinkMacSystemFont, &quot;Apple SD Gothic Neo&quot;, &quot;Noto Sans KR&quot;, &quot;Malgun Gothic&quot;, sans-serif;
      line-height: 1.85;
      letter-spacing: -0.02em;
      background:
        radial-gradient(circle at 12% 4%, rgba(216, 188, 118, 0.16), transparent 32%),
        radial-gradient(circle at 90% 12%, rgba(123, 67, 48, 0.22), transparent 34%),
        linear-gradient(145deg, #171411 0%, #0c0c0d 56%, #17120f 100%);
      border-radius: 28px;
      overflow: hidden;
      box-shadow: var(--zard-shadow);
    }

    .zard_memorial_wrap * {
      box-sizing: border-box;
    }

    .zard_memorial_wrap p {
      margin: 0 0 18px;
      word-break: keep-all;
    }

    .zard_memorial_wrap a {
      color: #f4d98e;
      text-decoration: none;
      border-bottom: 1px solid rgba(244, 217, 142, 0.35);
    }

    .zard_memorial_wrap a:hover {
      border-bottom-color: #f4d98e;
    }

    .zard_memorial_wrap img {
      max-width: 100%;
      height: auto;
    }

    .zard_hero {
      position: relative;
      background: #0b0b0b;
      overflow: hidden;
    }

    .zard_thumb {
      margin: 0 !important;
      padding: 0;
      line-height: 0;
      position: relative;
      overflow: hidden;
      background: #111;
    }

    .zard_thumb p {
      margin: 0 !important;
      line-height: 0;
    }

    .zard_thumb::after {
      content: &quot;&quot;;
      position: absolute;
      inset: 0;
      background:
        linear-gradient(to bottom, rgba(0,0,0,0.02), rgba(0,0,0,0.38)),
        radial-gradient(circle at 18% 88%, rgba(216, 188, 118, 0.24), transparent 34%);
      pointer-events: none;
    }

    .zard_hero_text {
      position: relative;
      padding: 56px 44px 62px;
      border-top: 1px solid rgba(255,255,255,0.08);
      background:
        linear-gradient(180deg, rgba(0,0,0,0.68), rgba(0,0,0,0.18)),
        radial-gradient(circle at 18% 18%, rgba(216, 188, 118, 0.14), transparent 34%);
      overflow: hidden;
    }

    .zard_hero_text::before {
      content: &quot;ZARD&quot;;
      position: absolute;
      right: -18px;
      top: 4px;
      color: rgba(255,255,255,0.04);
      font-family: Georgia, &quot;Times New Roman&quot;, serif;
      font-size: clamp(90px, 18vw, 190px);
      font-weight: 700;
      letter-spacing: 0.08em;
      line-height: 1;
      pointer-events: none;
      z-index: 0;
    }

    .zard_hero_text::after {
      content: &quot;&quot;;
      position: absolute;
      left: 44px;
      bottom: 0;
      width: 180px;
      height: 2px;
      background: linear-gradient(90deg, var(--zard-gold), transparent);
      opacity: 0.9;
    }

    .zard_eyebrow {
      position: relative;
      z-index: 1;
      display: inline-flex;
      align-items: center;
      gap: 12px;
      color: var(--zard-gold2);
      font-size: 14px;
      letter-spacing: 0.18em;
      text-transform: uppercase;
      margin-bottom: 22px;
      font-weight: 800;
    }

    .zard_eyebrow::before {
      content: &quot;&quot;;
      width: 38px;
      height: 1px;
      background: var(--zard-gold2);
      opacity: 0.95;
    }

    .zard_title_box {
      position: relative;
      z-index: 1;
      max-width: 900px;
      padding: 28px 28px 31px;
      border-radius: 28px;
      background:
        linear-gradient(135deg, rgba(0,0,0,0.74), rgba(255,255,255,0.055)),
        rgba(0,0,0,0.32);
      border: 1px solid rgba(216, 188, 118, 0.36);
      box-shadow:
        0 18px 64px rgba(0,0,0,0.52),
        inset 0 1px 0 rgba(255,255,255,0.1);
      backdrop-filter: blur(8px);
    }

    .zard_title {
      position: relative;
      margin: 0;
      font-family: &quot;Noto Serif KR&quot;, Georgia, &quot;Times New Roman&quot;, serif;
      line-height: 1.13;
      letter-spacing: -0.055em;
      text-shadow:
        0 2px 0 rgba(0,0,0,0.6),
        0 12px 38px rgba(0,0,0,0.78),
        0 0 28px rgba(216,188,118,0.25);
    }

    .zard_title .small {
      display: block;
      margin-bottom: 10px;
      font-size: clamp(18px, 3.2vw, 28px);
      color: var(--zard-gold2);
      letter-spacing: -0.02em;
      font-weight: 700;
    }

    .zard_title .main {
      display: block;
      font-size: clamp(34px, 6.2vw, 66px);
      color: #fffdf7;
      font-weight: 900;
    }

    .zard_title .sub {
      display: block;
      margin-top: 14px;
      font-size: clamp(20px, 3.8vw, 38px);
      color: #f2ddba;
      font-weight: 500;
      letter-spacing: -0.035em;
    }

    .zard_title .jp {
      display: block;
      margin-top: 16px;
      color: #f7e7c2;
      font-size: clamp(16px, 2.8vw, 23px);
      letter-spacing: 0.01em;
      font-weight: 500;
      opacity: 0.96;
    }

    .zard_title_line {
      width: 100%;
      height: 1px;
      margin: 24px 0 0;
      background: linear-gradient(90deg, var(--zard-gold), rgba(255,255,255,0.18), transparent);
      opacity: 0.9;
    }

    .zard_subtitle {
      position: relative;
      z-index: 1;
      margin-top: 28px;
      max-width: 840px;
      color: #eee4d8;
      font-size: 18px;
    }

    .zard_meta_chips {
      position: relative;
      z-index: 1;
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin: 30px 0 0;
      padding: 0;
      list-style: none;
    }

    .zard_meta_chips {
      list-style: none !important;
    }

    .zard_meta_chips span {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 9px 13px;
      border-radius: 999px;
      background: rgba(216, 188, 118, 0.12);
      border: 1px solid rgba(216, 188, 118, 0.28);
      color: #f5e2b3;
      font-size: 13px;
      font-weight: 700;
      letter-spacing: -0.01em;
      line-height: 1.35;
      white-space: nowrap;
    }

    .zard_meta_chips li,
    .zard_meta_chips span {
      list-style: none !important;
    }

    .zard_meta_chips li::before,
    .zard_meta_chips li::after,
    .zard_meta_chips span::before,
    .zard_meta_chips span::after,
    .zard_meta_chips li::marker {
      content: none !important;
      display: none !important;
    }

    .zard_quote {
      position: relative;
      z-index: 1;
      margin: 36px 0 0;
      padding: 25px 27px;
      border-left: 3px solid var(--zard-gold);
      background: linear-gradient(90deg, rgba(216, 188, 118, 0.15), rgba(255,255,255,0.04));
      border-radius: 0 18px 18px 0;
      color: #fff7e7;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
      font-size: 19px;
      line-height: 1.85;
      text-shadow: 0 4px 22px rgba(0,0,0,0.5);
    }

    .zard_body {
      padding: 46px 44px 54px;
    }

    .zard_section {
      margin: 0 0 52px;
    }

    .zard_section h2 {
      margin: 0 0 22px;
      color: #fff7e7;
      font-size: clamp(24px, 4vw, 34px);
      line-height: 1.35;
      letter-spacing: -0.045em;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
      text-shadow: 0 10px 28px rgba(0,0,0,0.32);
    }

    .zard_section h2::after {
      content: &quot;&quot;;
      display: block;
      width: 64px;
      height: 2px;
      margin-top: 14px;
      background: linear-gradient(90deg, var(--zard-gold), transparent);
      opacity: 0.95;
    }

    .zard_lead {
      font-size: 18px;
      color: #f2ebe1;
    }

    .zard_note {
      margin: 24px 0;
      padding: 22px 24px;
      border-radius: 20px;
      background:
        linear-gradient(135deg, rgba(216,188,118,0.12), rgba(255,255,255,0.04)),
        rgba(255,255,255,0.045);
      border: 1px solid rgba(216,188,118,0.26);
      color: #f7ebd8;
    }

    .zard_info_grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 14px;
      margin: 30px 0 22px;
    }

    .zard_info_card {
      padding: 22px 20px;
      background: var(--zard-card);
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: 20px;
      backdrop-filter: blur(10px);
    }

    .zard_info_card strong {
      display: block;
      margin-bottom: 8px;
      color: var(--zard-gold2);
      font-size: 13px;
      letter-spacing: 0.08em;
    }

    .zard_info_card span {
      display: block;
      color: #fffaf3;
      font-size: 18px;
      font-weight: 800;
      line-height: 1.45;
    }

    .zard_realname_panel {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 14px;
      margin: 30px 0 28px;
    }

    .zard_realname_card {
      padding: 21px 20px;
      border-radius: 20px;
      background:
        linear-gradient(135deg, rgba(216,188,118,0.12), rgba(255,255,255,0.045)),
        rgba(255,255,255,0.06);
      border: 1px solid rgba(216,188,118,0.22);
    }

    .zard_realname_card b {
      display: block;
      margin-bottom: 8px;
      color: #f4dc9a;
      font-size: 13px;
      letter-spacing: 0.08em;
    }

    .zard_realname_card span {
      display: block;
      color: #fff7e7;
      font-size: 17px;
      line-height: 1.55;
      font-weight: 700;
    }

    .zard_realname_card ruby {
      ruby-position: over;
    }

    .zard_realname_card rt {
      color: #d8c6a0;
      font-size: 10px;
      font-weight: 500;
    }

    .zard_personal_box {
      position: relative;
      padding: 30px;
      border-radius: 26px;
      background:
        radial-gradient(circle at 10% 0%, rgba(216,188,118,0.18), transparent 36%),
        linear-gradient(135deg, rgba(255,255,255,0.09), rgba(255,255,255,0.035));
      border: 1px solid rgba(255,255,255,0.1);
      overflow: hidden;
    }

    .zard_personal_box::before {
      content: &quot;MEMORY&quot;;
      position: absolute;
      right: -8px;
      bottom: -28px;
      color: rgba(255,255,255,0.045);
      font-family: Georgia, serif;
      font-size: 82px;
      letter-spacing: 0.08em;
      line-height: 1;
      pointer-events: none;
    }

    .zard_song_list {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 14px;
      margin-top: 26px;
    }

    .zard_song {
      padding: 21px 20px 19px;
      border-radius: 18px;
      background: rgba(255,255,255,0.07);
      border: 1px solid rgba(255,255,255,0.08);
      transition: transform 0.25s ease, background 0.25s ease, border-color 0.25s ease;
    }

    .zard_song:hover {
      transform: translateY(-3px);
      background: rgba(255,255,255,0.11);
      border-color: rgba(216,188,118,0.3);
    }

    .zard_song b {
      display: block;
      color: #fff7e7;
      font-size: 18px;
      margin-bottom: 7px;
    }

    .zard_song small {
      display: block;
      color: var(--zard-muted);
      font-size: 14px;
      line-height: 1.7;
    }

    .zard_photo_gallery {
      margin: 34px 0 8px;
      padding: 28px;
      border-radius: 26px;
      background:
        radial-gradient(circle at 8% 0%, rgba(216,188,118,0.16), transparent 35%),
        rgba(255,255,255,0.052);
      border: 1px solid rgba(255,255,255,0.09);
    }

    .zard_photo_gallery_head {
      margin-bottom: 22px;
    }

    .zard_photo_gallery_head h3 {
      margin: 0 0 10px;
      color: #fff7e7;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
      font-size: 24px;
      line-height: 1.35;
      letter-spacing: -0.04em;
    }

    .zard_photo_gallery_head p {
      margin: 0;
      color: #cfc5b8;
      font-size: 15px;
      line-height: 1.75;
    }

    .zard_photo_grid p {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 14px;
      margin: 0 !important;
    }

    .zard_photo_grid img {
      width: 100%;
      height: 260px;
      object-fit: cover;
      border-radius: 18px;
      box-shadow: 0 18px 42px rgba(0,0,0,0.32);
      border: 1px solid rgba(255,255,255,0.1);
      background: #111;
    }

    .zard_photo_caption {
      margin-top: 18px;
      color: #d9cdbc;
      font-size: 14px;
      line-height: 1.7;
      text-align: center;
    }

    .zard_lang_grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 16px;
      margin-top: 26px;
    }

    .zard_lang_card {
      padding: 24px 24px 22px;
      border-radius: 22px;
      background:
        linear-gradient(135deg, rgba(216,188,118,0.11), rgba(255,255,255,0.04)),
        rgba(255,255,255,0.045);
      border: 1px solid rgba(216,188,118,0.22);
    }

    .zard_lang_card h3 {
      margin: 0 0 12px;
      color: #f4dc9a;
      font-size: 17px;
      letter-spacing: 0.02em;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
    }

    .zard_lang_card p {
      color: #f5eadb;
      font-size: 16px;
      line-height: 1.85;
    }

    .zard_video_area {
      margin-top: 30px;
    }

    .zard_video_intro {
      margin-bottom: 20px;
      color: #f2e6d7;
    }

    .zard_video_grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 18px;
    }

    .zard_video_card {
      padding: 18px;
      border-radius: 22px;
      background: rgba(255,255,255,0.07);
      border: 1px solid rgba(255,255,255,0.09);
    }

    .zard_video_card h3 {
      margin: 0 0 12px;
      color: #fff4df;
      font-size: 18px;
      line-height: 1.4;
      letter-spacing: -0.03em;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
    }

    .zard_video_card p {
      margin: 12px 0 0;
      color: var(--zard-muted);
      font-size: 14px;
      line-height: 1.7;
    }

    .zard_video_embed {
      position: relative;
      width: 100%;
      padding-top: 56.25%;
      overflow: hidden;
      border-radius: 16px;
      background: #000;
      box-shadow: 0 16px 34px rgba(0,0,0,0.28);
    }

    .zard_video_embed iframe {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      border: 0;
    }

    .zard_timeline {
      margin-top: 28px;
      border-left: 1px solid var(--zard-line);
      padding-left: 22px;
    }

    .zard_time_item {
      position: relative;
      padding: 0 0 23px 18px;
    }

    .zard_time_item::before {
      content: &quot;&quot;;
      position: absolute;
      left: -28px;
      top: 8px;
      width: 11px;
      height: 11px;
      border-radius: 999px;
      background: var(--zard-gold);
      box-shadow: 0 0 0 6px rgba(216, 188, 118, 0.12);
    }

    .zard_time_item b {
      display: block;
      color: var(--zard-gold2);
      font-size: 15px;
      margin-bottom: 4px;
    }

    .zard_time_item span {
      color: #f4eee6;
    }

    .zard_closing {
      margin-top: 42px;
      padding: 40px 30px;
      text-align: center;
      border-radius: 26px;
      background:
        radial-gradient(circle at 50% 0%, rgba(216,188,118,0.18), transparent 42%),
        rgba(255,255,255,0.055);
      border: 1px solid rgba(255,255,255,0.1);
    }

    .zard_closing .zard_final {
      margin: 0 auto 22px;
      max-width: 780px;
      color: #fff8ed;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
      font-size: clamp(22px, 4vw, 31px);
      line-height: 1.68;
      letter-spacing: -0.04em;
    }

    .zard_last_words {
      max-width: 780px;
      margin: 28px auto 0;
      padding-top: 26px;
      border-top: 1px solid rgba(216,188,118,0.24);
      color: #f0dfc3;
      font-family: &quot;Noto Serif KR&quot;, Georgia, serif;
      font-size: 18px;
      line-height: 1.9;
    }

    .zard_last_words .jp {
      display: block;
      margin-top: 14px;
      color: #f5dfad;
      font-size: 16px;
      letter-spacing: 0.01em;
    }

    .zard_last_words .en {
      display: block;
      margin-top: 10px;
      color: #d9cdbc;
      font-size: 15px;
      font-family: Georgia, &quot;Times New Roman&quot;, serif;
      letter-spacing: 0.01em;
    }

    .zard_signature {
      display: inline-block;
      margin-top: 26px;
      padding: 10px 18px;
      border-radius: 999px;
      color: var(--zard-gold2);
      border: 1px solid rgba(216,188,118,0.34);
      background: rgba(0,0,0,0.18);
      font-size: 14px;
      letter-spacing: 0.04em;
    }

    .zard_sources {
      margin-top: 40px;
      padding: 24px;
      border-radius: 20px;
      background: rgba(0,0,0,0.2);
      border: 1px solid rgba(255,255,255,0.08);
    }

    .zard_sources h3 {
      margin: 0 0 14px;
      color: #fff7e7;
      font-size: 19px;
    }

    .zard_sources ul {
      margin: 0;
      padding-left: 18px;
      color: var(--zard-muted);
    }

    .zard_sources li {
      margin: 8px 0;
    }

    .zard_seo_keywords {
      margin-top: 24px;
      padding: 20px;
      border-radius: 18px;
      background: rgba(255,255,255,0.045);
      border: 1px solid rgba(255,255,255,0.08);
      color: #d9cdbc;
      font-size: 14px;
      line-height: 1.8;
    }

    @media (max-width: 768px) {
      .zard_memorial_wrap {
        border-radius: 18px;
      }

      .zard_hero_text,
      .zard_body {
        padding: 32px 22px;
      }

      .zard_title_box {
        padding: 23px 18px 25px;
        border-radius: 22px;
      }

      .zard_subtitle,
      .zard_lead {
        font-size: 16px;
      }

      .zard_quote {
        font-size: 16px;
        padding: 20px;
      }

      .zard_info_grid,
      .zard_realname_panel,
      .zard_song_list,
      .zard_video_grid {
        grid-template-columns: 1fr;
      }

      .zard_personal_box,
      .zard_closing {
        padding: 24px 20px;
      }

      .zard_photo_gallery {
        padding: 22px 16px;
      }

      .zard_photo_grid p {
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
      }

      .zard_photo_grid img {
        height: 180px;
        border-radius: 14px;
      }

      .zard_last_words {
        font-size: 16px;
      }
    }
  &lt;/style&gt;
&lt;article&gt;&lt;header class=&quot;zard_hero&quot;&gt;
&lt;figure class=&quot;zard_thumb&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/euxgYC/dJMcafzXO68/NYp98eNtkp4uj7032gbDv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/euxgYC/dJMcafzXO68/NYp98eNtkp4uj7032gbDv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/euxgYC/dJMcafzXO68/NYp98eNtkp4uj7032gbDv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeuxgYC%2FdJMcafzXO68%2FNYp98eNtkp4uj7032gbDv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;figure class=&quot;zard_thumb&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/figure&gt;
&lt;div class=&quot;zard_hero_text&quot;&gt;
&lt;div class=&quot;zard_eyebrow&quot;&gt;May 27 Memorial &amp;middot; 5月27日 命日&lt;/div&gt;
&lt;div class=&quot;zard_title_box&quot;&gt;
&lt;h1 class=&quot;zard_title&quot;&gt;&lt;span class=&quot;small&quot;&gt;5월 27일, ZARD 사카이 이즈미를 기억하며&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;그리움은 노래가 되어 남았다&lt;/span&gt; &lt;span class=&quot;sub&quot;&gt;坂井泉水, 아직도 마음속에서 재생되는 목소리&lt;/span&gt; &lt;span class=&quot;jp&quot;&gt;ZARD &amp;middot; 坂井泉水 追悼 | Izumi Sakai Memorial Tribute&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;zard_title_line&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p class=&quot;zard_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;5월 27일은 일본의 전설적인 음악 유닛 ZARD의 보컬이자 작사가였던 사카이 이즈미, 일본어 이름으로는 坂井泉水, 영어로는 Izumi Sakai 또는 Sakai Izumi를 기억하게 되는 날입니다. 본명은 蒲池幸子, Sachiko Kamachi입니다. 오늘은 그녀가 남긴 목소리와 노랫말, 그리고 뒤늦게 ZARD를 알게 된 한 사람의 마음으로 조용히 추모의 글을 남겨봅니다.&lt;/p&gt;
&lt;div class=&quot;zard_meta_chips&quot; role=&quot;list&quot;&gt;&lt;span&gt;ZARD&lt;/span&gt; &lt;span&gt;자드&lt;/span&gt; &lt;span&gt;坂井泉水&lt;/span&gt; &lt;span&gt;さかい いずみ&lt;/span&gt; &lt;span&gt;Izumi Sakai&lt;/span&gt; &lt;span&gt;蒲池幸子&lt;/span&gt; &lt;span&gt;Sachiko Kamachi&lt;/span&gt; &lt;span&gt;5月27日 命日&lt;/span&gt; &lt;span&gt;ZARD 追悼&lt;/span&gt; &lt;span&gt;負けないで&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_quote&quot;&gt;사람은 떠났지만, 목소리는 남았습니다.&lt;br /&gt;그리고 그 목소리는 지금도 누군가의 지친 하루에 조용히 기대어 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/header&gt;&lt;main class=&quot;zard_body&quot;&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5월 27일, 다시 ZARD를 듣는 날&lt;/h2&gt;
&lt;p class=&quot;zard_lead&quot; data-ke-size=&quot;size16&quot;&gt;매년 5월 27일이 다가오면 자연스럽게 ZARD의 노래를 다시 듣게 됩니다. 누군가에게는 오래된 J-POP의 추억일 수 있고, 누군가에게는 1990년대 일본 음악을 대표하는 이름일 수 있습니다. 하지만 저에게 ZARD는 조금 다른 의미로 남아 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 1994년생입니다. 2007년, 사카이 이즈미가 세상을 떠났던 그해에는 중학교 1학년이었습니다. 당시에는 ZARD라는 이름을 깊이 알지는 못했습니다. 오히려 「負けないで」라는 노래도 처음에는 &lt;b&gt;반올림&lt;/b&gt;에 나왔던 전혜선의 「지지마」라는 노래로 먼저 기억하고 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 몇 년 전, 우연히 일본 노래를 듣다가 ZARD를 제대로 알게 되었습니다. 처음에는 익숙한 멜로디가 반가워서 듣기 시작했지만, 어느 순간 ZARD의 노래들을 하나씩 찾아 듣고 있었습니다. 대표곡만 들은 것이 아니라 앨범과 라이브 영상, 관련 곡들까지 계속 이어서 듣게 되었고, 그때부터 사카이 이즈미의 목소리는 제 플레이리스트 안에서 오래 머무는 이름이 되었습니다.&lt;/p&gt;
&lt;div class=&quot;zard_note&quot;&gt;ZARD의 노래는 단순히 옛날 노래라서 좋은 것이 아니었습니다. 지쳤을 때 다시 일으켜 세워주는 노래였고, 마음을 너무 과하게 흔들지 않으면서도 조용히 옆에 있어주는 음악이었습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사카이 이즈미, 坂井泉水, 그리고 본명 蒲池幸子&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZARD를 이야기할 때 가장 먼저 떠오르는 이름은 사카이 이즈미입니다. 일본어로는 坂井泉水, 히라가나로는 さかい いずみ, 영어권에서는 Izumi Sakai 또는 Sakai Izumi로 표기됩니다. 그리고 그녀의 본명은 蒲池 幸子, 한국어로 읽으면 가마치 사치코, 영어 표기로는 Sachiko Kamachi 또는 Kamachi Sachiko입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 한국어 독자를 위해 주로 사카이 이즈미라고 적지만, 일본과 해외 검색 유입을 함께 고려해 坂井泉水, さかい いずみ, Izumi Sakai, Sakai Izumi, 蒲池幸子, Sachiko Kamachi 표기를 함께 남깁니다. 이름은 다르게 적히지만, 결국 우리가 기억하는 사람은 ZARD의 목소리로 오래 남아 있는 한 사람입니다.&lt;/p&gt;
&lt;div class=&quot;zard_realname_panel&quot;&gt;
&lt;div class=&quot;zard_realname_card&quot;&gt;&lt;b&gt;한국어 표기&lt;/b&gt; &lt;span&gt;사카이 이즈미&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_realname_card&quot;&gt;&lt;b&gt;활동명&lt;/b&gt; &lt;span&gt;坂井泉水&lt;br /&gt;さかい いずみ&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_realname_card&quot;&gt;&lt;b&gt;영어 표기&lt;/b&gt; &lt;span&gt;Izumi Sakai&lt;br /&gt;Sakai Izumi&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_realname_card&quot;&gt;&lt;b&gt;본명&lt;/b&gt; &lt;span&gt; &lt;ruby&gt;蒲池&lt;rt&gt;かまち&lt;/rt&gt;&lt;/ruby&gt; &lt;ruby&gt;幸子&lt;rt&gt;さちこ&lt;/rt&gt;&lt;/ruby&gt;&lt;br /&gt;Sachiko Kamachi &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZARD는 사카이 이즈미를 중심으로 한 음악 유닛입니다. 1991년 2월 10일 「Good-bye My Loneliness」로 데뷔한 뒤, 수많은 싱글과 앨범을 발표하며 1990년대 일본 대중음악의 한 시대를 대표하는 이름이 되었습니다. 공식 프로필에 따르면 ZARD는 현재까지 45장의 싱글과 22장의 앨범을 발표했습니다.&lt;/p&gt;
&lt;div class=&quot;zard_info_grid&quot;&gt;
&lt;div class=&quot;zard_info_card&quot;&gt;&lt;b&gt;ARTIST&lt;/b&gt; &lt;span&gt;ZARD / 坂井泉水&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_info_card&quot;&gt;&lt;b&gt;REAL NAME&lt;/b&gt; &lt;span&gt;蒲池幸子&lt;br /&gt;Sachiko Kamachi&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_info_card&quot;&gt;&lt;b&gt;MEMORIAL DAY&lt;/b&gt; &lt;span&gt;2007.05.27&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유행이 지나도 바래지 않는 노래. 오래전에 발표되었지만 지금의 마음에도 닿는 목소리. 그리고 세월이 흘러도 다시 찾아 듣게 되는 음악. 그것이 ZARD가 가진 힘이고, 사카이 이즈미가 남긴 가장 큰 선물이라고 생각합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;뒤늦게 알게 되었지만, 오래 좋아하게 된 노래들&lt;/h2&gt;
&lt;div class=&quot;zard_personal_box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZARD를 좋아하게 된 뒤 가장 많이 들었던 곡 중 하나는 역시 「負けないで」였습니다. 제목 그대로 &amp;ldquo;지지 말라&amp;rdquo;는 메시지를 담고 있지만, 이상하게도 이 노래는 억지로 힘내라고 밀어붙이지 않습니다. 오히려 지쳐 있던 제 자신에게 조용히 손을 내밀어주는 느낌이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;「心を開いて」도 정말 좋아하는 곡입니다. 흔한 사랑 노래처럼 들릴 수도 있지만, 막상 가사를 곱씹어보면 단순한 연애 감정보다 사람과 사람 사이의 거리, 마음을 열기까지의 조심스러움, 그리고 진심을 전하고 싶은 마음이 더 크게 다가옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;「突然」 역시 인상 깊었습니다. 이 곡은 FIELD OF VIEW의 곡으로 알려져 있지만, 사카이 이즈미가 작사한 곡이기도 합니다. 그래서인지 곡 안에 흐르는 말의 온도와 정서는 ZARD를 좋아하는 사람에게도 자연스럽게 닿습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 「揺れる想い」는 ZARD 특유의 청량함과 그리움이 가장 잘 살아 있는 곡 중 하나라고 생각합니다. 밝은 듯하지만 가볍지 않고, 그리운 듯하지만 슬픔에만 머물지 않는 그 감정이 참 좋았습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_song_list&quot;&gt;
&lt;div class=&quot;zard_song&quot;&gt;&lt;b&gt;負けないで&lt;/b&gt; &lt;small&gt;지쳤던 제 자신에게 가장 직접적으로 위로가 되었던 노래. 포기하지 말라는 말을 가장 부드럽게 건네는 곡입니다.&lt;/small&gt;&lt;/div&gt;
&lt;div class=&quot;zard_song&quot;&gt;&lt;b&gt;心を開いて&lt;/b&gt; &lt;small&gt;뻔한 사랑 노래라기보다, 마음을 열어가는 과정과 진심의 거리를 섬세하게 느끼게 해준 곡입니다.&lt;/small&gt;&lt;/div&gt;
&lt;div class=&quot;zard_song&quot;&gt;&lt;b&gt;突然&lt;/b&gt; &lt;small&gt;FIELD OF VIEW의 곡이지만 사카이 이즈미가 작사한 노래. ZARD를 좋아하는 사람이라면 자연스럽게 마음이 가는 곡입니다.&lt;/small&gt;&lt;/div&gt;
&lt;div class=&quot;zard_song&quot;&gt;&lt;b&gt;揺れる想い&lt;/b&gt; &lt;small&gt;ZARD의 청량함과 아련함이 함께 담긴 곡. 오래 들어도 색이 바래지 않는 1990년대 J-POP의 명곡입니다.&lt;/small&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사진으로 남아 있는 사카이 이즈미의 시간들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZARD의 음악을 듣다 보면 사카이 이즈미의 목소리뿐 아니라, 조용하고 담백한 분위기의 사진들도 함께 떠오릅니다. 무대 위의 화려함보다 차분한 시선과 편안한 표정으로 오래 기억되는 사람. 아래 사진들은 ZARD의 노래가 남긴 기억처럼, 조용히 마음에 남는 사카이 이즈미의 여러 순간들입니다.&lt;/p&gt;
&lt;div class=&quot;zard_photo_gallery&quot;&gt;
&lt;div class=&quot;zard_photo_gallery_head&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;坂井泉水 Photo Memory&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진은 한 사람의 모든 시간을 설명할 수는 없지만, 음악과 함께 남은 분위기를 다시 떠올리게 합니다. ZARD를 들을 때마다 다시 만나게 되는 사카이 이즈미의 모습입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_photo_grid&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;32323.jpg&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccI8wa/dJMcadhQpCA/rmxoj62sk6w9rA6eF2w4nK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccI8wa/dJMcadhQpCA/rmxoj62sk6w9rA6eF2w4nK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccI8wa/dJMcadhQpCA/rmxoj62sk6w9rA6eF2w4nK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccI8wa%2FdJMcadhQpCA%2Frmxoj62sk6w9rA6eF2w4nK%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;736&quot; height=&quot;456&quot; data-filename=&quot;32323.jpg&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562825.jpg&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SPNPp/dJMcadB2aK5/fJN2Rl5FtWAESEyK8qJf81/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SPNPp/dJMcadB2aK5/fJN2Rl5FtWAESEyK8qJf81/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SPNPp/dJMcadB2aK5/fJN2Rl5FtWAESEyK8qJf81/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSPNPp%2FdJMcadB2aK5%2FfJN2Rl5FtWAESEyK8qJf81%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;423&quot; height=&quot;423&quot; data-filename=&quot;1779562825.jpg&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562719.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;997&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bchvoo/dJMcadB2aK6/QTkHeUOh0ayTTkc3T7wJ40/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bchvoo/dJMcadB2aK6/QTkHeUOh0ayTTkc3T7wJ40/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bchvoo/dJMcadB2aK6/QTkHeUOh0ayTTkc3T7wJ40/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbchvoo%2FdJMcadB2aK6%2FQTkHeUOh0ayTTkc3T7wJ40%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;850&quot; height=&quot;997&quot; data-filename=&quot;1779562719.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562669.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cch5oh/dJMcabRNRuO/XtJKQKToLYJu9kCd15g2D1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cch5oh/dJMcabRNRuO/XtJKQKToLYJu9kCd15g2D1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cch5oh/dJMcabRNRuO/XtJKQKToLYJu9kCd15g2D1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcch5oh%2FdJMcabRNRuO%2FXtJKQKToLYJu9kCd15g2D1%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;850&quot; height=&quot;850&quot; data-filename=&quot;1779562669.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562644.jpg&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ApcZw/dJMcadhQpCB/osyk0pOvGKSXSKpuj80Xek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ApcZw/dJMcadhQpCB/osyk0pOvGKSXSKpuj80Xek/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ApcZw/dJMcadhQpCB/osyk0pOvGKSXSKpuj80Xek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FApcZw%2FdJMcadhQpCB%2Fosyk0pOvGKSXSKpuj80Xek%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;554&quot; height=&quot;656&quot; data-filename=&quot;1779562644.jpg&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562642.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;1257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dffw0B/dJMcabRNRuP/pHQDHubfLTJRhO0tVpGAqK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dffw0B/dJMcabRNRuP/pHQDHubfLTJRhO0tVpGAqK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dffw0B/dJMcabRNRuP/pHQDHubfLTJRhO0tVpGAqK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdffw0B%2FdJMcabRNRuP%2FpHQDHubfLTJRhO0tVpGAqK%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;850&quot; height=&quot;1257&quot; data-filename=&quot;1779562642.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;1257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562576.gif&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk3dCw/dJMcadB2aLk/IUAgLrqJvdthcEipMvDRj1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk3dCw/dJMcadB2aLk/IUAgLrqJvdthcEipMvDRj1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk3dCw/dJMcadB2aLk/IUAgLrqJvdthcEipMvDRj1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bk3dCw/dJMcadB2aLk/IUAgLrqJvdthcEipMvDRj1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;273&quot; data-filename=&quot;1779562576.gif&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562559.jpg&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UUeSt/dJMcadB2aK7/GLAwdK2d7Y12C9rLQhpU61/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UUeSt/dJMcadB2aK7/GLAwdK2d7Y12C9rLQhpU61/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UUeSt/dJMcadB2aK7/GLAwdK2d7Y12C9rLQhpU61/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUUeSt%2FdJMcadB2aK7%2FGLAwdK2d7Y12C9rLQhpU61%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;580&quot; height=&quot;773&quot; data-filename=&quot;1779562559.jpg&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_09.gif&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;599&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK4G7q/dJMcabRNRuU/an8HkTv1SNkAFyAN19I2Ak/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK4G7q/dJMcabRNRuU/an8HkTv1SNkAFyAN19I2Ak/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK4G7q/dJMcabRNRuU/an8HkTv1SNkAFyAN19I2Ak/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cK4G7q/dJMcabRNRuU/an8HkTv1SNkAFyAN19I2Ak/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;802&quot; height=&quot;599&quot; data-filename=&quot;KakaoTalk_20260524_035310345_09.gif&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;599&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345.jpg&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zz31e/dJMcadB2aK8/vK1gK09tIgAyhkASERED7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zz31e/dJMcadB2aK8/vK1gK09tIgAyhkASERED7k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zz31e/dJMcadB2aK8/vK1gK09tIgAyhkASERED7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZz31e%2FdJMcadB2aK8%2FvK1gK09tIgAyhkASERED7k%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;332&quot; height=&quot;443&quot; data-filename=&quot;KakaoTalk_20260524_035310345.jpg&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_01.jpg&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;867&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chdRTh/dJMcadB2aK9/KcsBrtUN6b1BYYADmNxodK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chdRTh/dJMcadB2aK9/KcsBrtUN6b1BYYADmNxodK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chdRTh/dJMcadB2aK9/KcsBrtUN6b1BYYADmNxodK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchdRTh%2FdJMcadB2aK9%2FKcsBrtUN6b1BYYADmNxodK%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;600&quot; height=&quot;867&quot; data-filename=&quot;KakaoTalk_20260524_035310345_01.jpg&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;867&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_02.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;1010&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKMQ3I/dJMcadhQpCC/2FUbSl7UkoyIZKcs0Rn4ik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKMQ3I/dJMcadhQpCC/2FUbSl7UkoyIZKcs0Rn4ik/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKMQ3I/dJMcadhQpCC/2FUbSl7UkoyIZKcs0Rn4ik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKMQ3I%2FdJMcadhQpCC%2F2FUbSl7UkoyIZKcs0Rn4ik%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;800&quot; height=&quot;1010&quot; data-filename=&quot;KakaoTalk_20260524_035310345_02.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;1010&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_03.jpg&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pPqyg/dJMcadB2aLb/WHo9Kscp00lBaDm2vVyUE1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pPqyg/dJMcadB2aLb/WHo9Kscp00lBaDm2vVyUE1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pPqyg/dJMcadB2aLb/WHo9Kscp00lBaDm2vVyUE1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpPqyg%2FdJMcadB2aLb%2FWHo9Kscp00lBaDm2vVyUE1%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;564&quot; height=&quot;564&quot; data-filename=&quot;KakaoTalk_20260524_035310345_03.jpg&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_04.jpg&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqLAXC/dJMcadB2aLc/pNCxAUWY2akmC4MoxT9UOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqLAXC/dJMcadB2aLc/pNCxAUWY2akmC4MoxT9UOk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqLAXC/dJMcadB2aLc/pNCxAUWY2akmC4MoxT9UOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqLAXC%2FdJMcadB2aLc%2FpNCxAUWY2akmC4MoxT9UOk%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;427&quot; height=&quot;640&quot; data-filename=&quot;KakaoTalk_20260524_035310345_04.jpg&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_05.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lDTf6/dJMcabRNRuQ/XjZxv0U5dW71iJ4Y4DXpUk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lDTf6/dJMcabRNRuQ/XjZxv0U5dW71iJ4Y4DXpUk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lDTf6/dJMcabRNRuQ/XjZxv0U5dW71iJ4Y4DXpUk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlDTf6%2FdJMcabRNRuQ%2FXjZxv0U5dW71iJ4Y4DXpUk%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;850&quot; height=&quot;850&quot; data-filename=&quot;KakaoTalk_20260524_035310345_05.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_06.jpg&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DPJtZ/dJMcadB2aLd/18XjHaDpKaTP4KOkKKafIK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DPJtZ/dJMcadB2aLd/18XjHaDpKaTP4KOkKKafIK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DPJtZ/dJMcadB2aLd/18XjHaDpKaTP4KOkKKafIK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDPJtZ%2FdJMcadB2aLd%2F18XjHaDpKaTP4KOkKKafIK%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;735&quot; height=&quot;1118&quot; data-filename=&quot;KakaoTalk_20260524_035310345_06.jpg&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_07.jpg&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lSVfD/dJMcadB2aLe/LrlkkdtWSPEDkfB73DNIZ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lSVfD/dJMcadB2aLe/LrlkkdtWSPEDkfB73DNIZ0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lSVfD/dJMcadB2aLe/LrlkkdtWSPEDkfB73DNIZ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlSVfD%2FdJMcadB2aLe%2FLrlkkdtWSPEDkfB73DNIZ0%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;563&quot; height=&quot;690&quot; data-filename=&quot;KakaoTalk_20260524_035310345_07.jpg&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260524_035310345_08.jpg&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crBS0x/dJMcadB2aLf/3RV6U2vhIVOgrGbDzGVeZ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crBS0x/dJMcadB2aLf/3RV6U2vhIVOgrGbDzGVeZ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crBS0x/dJMcadB2aLf/3RV6U2vhIVOgrGbDzGVeZ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrBS0x%2FdJMcadB2aLf%2F3RV6U2vhIVOgrGbDzGVeZ1%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;490&quot; height=&quot;355&quot; data-filename=&quot;KakaoTalk_20260524_035310345_08.jpg&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562889.jpg&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckjFiK/dJMcadB2aLg/rsI0PMGIi5F96zVuqJ1KJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckjFiK/dJMcadB2aLg/rsI0PMGIi5F96zVuqJ1KJ0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckjFiK/dJMcadB2aLg/rsI0PMGIi5F96zVuqJ1KJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckjFiK%2FdJMcadB2aLg%2FrsI0PMGIi5F96zVuqJ1KJ0%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;580&quot; height=&quot;773&quot; data-filename=&quot;1779562889.jpg&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562881.jpg&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVO7ED/dJMcabRNRuR/r2rCAwbL8ejdrNOTHyeDfK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVO7ED/dJMcabRNRuR/r2rCAwbL8ejdrNOTHyeDfK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVO7ED/dJMcabRNRuR/r2rCAwbL8ejdrNOTHyeDfK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVO7ED%2FdJMcabRNRuR%2Fr2rCAwbL8ejdrNOTHyeDfK%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;555&quot; height=&quot;1200&quot; data-filename=&quot;1779562881.jpg&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1779562846.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;959&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmcJkZ/dJMcadB2aLi/hkTPlFcqRjhdZ7oKkqcVq1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmcJkZ/dJMcadB2aLi/hkTPlFcqRjhdZ7oKkqcVq1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmcJkZ/dJMcadB2aLi/hkTPlFcqRjhdZ7oKkqcVq1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmcJkZ%2FdJMcadB2aLi%2FhkTPlFcqRjhdZ7oKkqcVq1%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;850&quot; height=&quot;959&quot; data-filename=&quot;1779562846.jpg&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;959&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;455455434.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxcXpK/dJMcabRNRuS/0Oiw7wvNcJFbqeQvXjWac1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxcXpK/dJMcabRNRuS/0Oiw7wvNcJFbqeQvXjWac1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxcXpK/dJMcabRNRuS/0Oiw7wvNcJFbqeQvXjWac1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxcXpK%2FdJMcabRNRuS%2F0Oiw7wvNcJFbqeQvXjWac1%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;640&quot; height=&quot;738&quot; data-filename=&quot;455455434.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;65465445.jpg&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/86M8H/dJMcabRNRuT/6iAvr6qJRrNdOLJeaOEHZ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/86M8H/dJMcabRNRuT/6iAvr6qJRrNdOLJeaOEHZ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/86M8H/dJMcabRNRuT/6iAvr6qJRrNdOLJeaOEHZ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F86M8H%2FdJMcabRNRuT%2F6iAvr6qJRrNdOLJeaOEHZ1%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;750&quot; height=&quot;593&quot; data-filename=&quot;65465445.jpg&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_photo_caption&quot;&gt;ZARD의 노래가 남긴 기억처럼, 사진 속 사카이 이즈미의 모습도 조용하고 오래 남습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;日本語と英語로 남기는 짧은 추모&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 한국어로 작성한 개인 추모 글이지만, ZARD와 坂井泉水를 기억하는 마음은 한국에만 머물지 않는다고 생각합니다. 일본의 팬들, 그리고 영어권에서 ZARD를 찾아 듣는 사람들도 이 글을 발견할 수 있도록 짧은 일본어와 영어 추모 문장을 함께 남깁니다.&lt;/p&gt;
&lt;div class=&quot;zard_lang_grid&quot;&gt;
&lt;div class=&quot;zard_lang_card&quot; lang=&quot;ja&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;日本語&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5月27日、ZARDのボーカリストであり作詞家であった坂井泉水さんを静かに偲びます。 彼女の歌声は、時が過ぎても色あせることなく、今も多くの人の心の中で優しく響き続けています。 「負けないで」「揺れる想い」「心を開いて」など、残された楽曲はこれからも大切な記憶として生き続けると思います。&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_lang_card&quot; lang=&quot;en&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;English&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;On May 27, I quietly remember Izumi Sakai, the voice and lyricist of ZARD. Her songs still carry a gentle warmth, giving comfort to those who feel tired, lost, or nostalgic. Even after many years, ZARD&amp;rsquo;s music remains alive in the hearts of listeners around the world.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;함께 듣고 싶은 ZARD의 노래&lt;/h2&gt;
&lt;p class=&quot;zard_video_intro&quot; data-ke-size=&quot;size16&quot;&gt;아래 영상들은 제가 ZARD와 사카이 이즈미를 떠올릴 때 함께 듣고 싶은 곡들입니다. 가사 전문을 옮기기보다는, 각 곡을 들으며 느낀 감정과 기억을 중심으로 남겨봅니다.&lt;/p&gt;
&lt;div class=&quot;zard_video_area&quot;&gt;
&lt;div class=&quot;zard_video_grid&quot;&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;眠れない夜を抱いて &amp;mdash; 1993년 8월 라이브&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/v5WKXOCUpSU?si=7FxNs5X-Kuk5PWyc&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;「眠れない夜を抱いて」를 1993년 8월에 라이브로 부른 영상입니다. ZARD 초창기의 생생한 분위기와 사카이 이즈미의 담백한 보컬을 함께 느낄 수 있는 자료입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;負けないで&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/_4DJkOUU648?si=FRoCiW8GB7keViBs&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;힘들 때마다 다시 듣게 되는 노래입니다. 크게 위로한다고 말하지 않지만, 어느새 다시 일어나야겠다는 마음을 만들어줍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;突然&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/AQgtj5txf1M?si=jhg-626lgGcjolwV&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FIELD OF VIEW의 곡으로 알려져 있지만 사카이 이즈미가 작사한 노래입니다. 밝은 멜로디 안에 묘하게 아련한 감정이 남습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;揺れる想い&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/jaFE9YH3Zmk?si=2A4z9yx-SvE_ezwM&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZARD의 청량함을 가장 잘 보여주는 곡 중 하나입니다. 시간이 흘러도 여전히 여름의 공기와 그리움이 함께 느껴집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;心を開いて&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/HUTbH6ywrXk?si=S0OJiGtg8xsrluwW&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 사랑 노래라기보다, 마음을 열고 누군가에게 다가가고 싶은 감정이 섬세하게 느껴지는 곡입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2007년 5월 27일, 너무 이른 이별&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미는 2007년 5월 27일, 향년 40세의 나이로 세상을 떠났습니다. 당시 그녀는 암 투병 중이었고, 병원에서 치료를 이어가고 있었습니다. 보도에 따르면 병원에서 산책 후 병실로 돌아가던 중 사고를 당했고, 결국 뇌좌상으로 세상을 떠났습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 이른 이별이었습니다. 더 많은 노래를 남길 수도 있었고, 더 많은 이야기를 들려줄 수도 있었던 사람이었기에 그녀의 부재는 지금도 많은 팬들에게 깊은 아쉬움으로 남아 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 시간이 흐를수록 더 분명해지는 것도 있습니다. 그녀가 떠난 뒤에도 ZARD의 음악은 멈추지 않았다는 사실입니다. 그녀의 목소리는 음반 속에, 영상 속에, 그리고 팬들의 기억 속에 계속 남아 있습니다.&lt;/p&gt;
&lt;div class=&quot;zard_timeline&quot;&gt;
&lt;div class=&quot;zard_time_item&quot;&gt;&lt;b&gt;1967년 2월 6일&lt;/b&gt; &lt;span&gt;蒲池幸子, 훗날 ZARD의 목소리로 기억될 사카이 이즈미가 태어남.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_time_item&quot;&gt;&lt;b&gt;1991년&lt;/b&gt; &lt;span&gt;ZARD, 「Good-bye My Loneliness」로 데뷔.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_time_item&quot;&gt;&lt;b&gt;1993년&lt;/b&gt; &lt;span&gt;「負けないで」, 「揺れる想い」 등을 통해 ZARD의 이름이 대중에게 깊이 각인.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_time_item&quot;&gt;&lt;b&gt;1995년&lt;/b&gt; &lt;span&gt;사카이 이즈미가 작사한 FIELD OF VIEW의 「突然」 발표.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_time_item&quot;&gt;&lt;b&gt;2007년 5월 27일&lt;/b&gt; &lt;span&gt;사카이 이즈미 별세. 그녀의 목소리는 이후에도 많은 사람들에게 이어짐.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_time_item&quot;&gt;&lt;b&gt;현재&lt;/b&gt; &lt;span&gt;ZARD의 음악은 여전히 많은 팬들에게 기억되고 다시 들리는 노래로 남아 있음.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2007년 당시 뉴스, 현장 기록, 그리고 생전 영상&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 영상들은 사카이 이즈미의 갑작스러운 이별을 전했던 당시 일본 언론 보도, 시간이 흐른 뒤 사고 장소를 찾아간 개인 영상, 그리고 생전의 목소리와 모습을 담은 자료들입니다. 추모 글의 분위기를 해치지 않도록 자극적으로 소비하기보다는, ZARD와 坂井泉水가 남긴 시간을 조용히 기록하고 기억하는 의미로 정리했습니다.&lt;/p&gt;
&lt;p class=&quot;zard_video_intro&quot; data-ke-size=&quot;size16&quot;&gt;사고와 관련된 영상은 보는 사람에 따라 마음이 무거울 수 있습니다. 이 글에서는 사건 자체보다, 한 시대를 지나온 목소리와 그 목소리를 기억하는 사람들의 마음에 초점을 두고 함께 남깁니다.&lt;/p&gt;
&lt;div class=&quot;zard_video_area&quot;&gt;
&lt;div class=&quot;zard_video_grid&quot;&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사카이 이즈미 관련 영상&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/ZDMR10hlOH4?si=Z8mZ96z6Fume2CiR&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미와 ZARD를 다시 떠올리게 하는 관련 영상입니다. 음악과 사진, 영상으로 남은 그녀의 분위기를 함께 정리해두기 좋은 자료입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사고 당시 관련 뉴스 영상&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/_rQzop3TKzI?si=fKDoeGNvHwM7tVsF&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2007년 당시 사카이 이즈미의 갑작스러운 사고 소식을 전했던 관련 뉴스 영상입니다. 지금 다시 보면 안타까움이 더 크게 다가오지만, 그녀가 얼마나 많은 사람들에게 기억되는 존재였는지도 느끼게 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2007년 사망 당시 일본 뉴스&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/ogjY90tHfDg?si=KGk4M-8LQFAFPf4w&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2007년 일본에서 보도된 사카이 이즈미 별세 관련 뉴스 영상입니다. 당시 팬들과 대중이 느꼈을 충격과 아쉬움을 생각하면, 그녀의 부재가 지금까지도 크게 남는 이유를 조금은 이해하게 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사망 당시 일본 언론 보도&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/NoF40OFvgH0?si=79P6hzIgCmOPZ4oP&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미의 별세 소식을 다룬 일본 언론 영상입니다. 여러 보도 자료를 함께 보면 당시 일본 음악계와 팬들이 느꼈던 상실감이 얼마나 컸는지 짐작하게 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사망 보도와 장례식 관련 영상&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/Nu8rZIsTXdA?si=jljKgPyvmOkTFYuC&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미의 별세 소식과 장례식 모습이 일부 담긴 영상입니다. 팬들에게는 단순한 뉴스가 아니라, 한 목소리와 작별해야 했던 순간의 기록처럼 느껴집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사고가 일어났던 현장 기록&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/AYh1mtoQ7-M?si=1YjTzBdjxyepcztk&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간이 꽤 흐른 뒤 일반인 또는 개인 유튜버가 촬영한 것으로 보이는 사고 현장 관련 영상입니다. 촬영 시점이 사고 당시와 다르기 때문에 당시 모습과는 차이가 있을 수 있으며, 장소를 단정하기보다는 추모와 기록의 맥락에서 조심스럽게 참고하는 자료로 보는 것이 좋겠습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;비교적 최근 묘소 방문 영상&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/XnKOlGqOM0A?si=0a3wD92B4Y86YqWn&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교적 최근 일본인이 사카이 이즈미의 묘소를 찾아간 것으로 보이는 개인 영상입니다. 시간이 흘러도 그녀를 기억하고 찾아가는 사람들이 있다는 사실은, ZARD의 음악이 여전히 현재형으로 남아 있음을 보여줍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;생전의 목소리와 인터뷰로 만나는 사카이 이즈미&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미는 대중 앞에 자주 모습을 드러내는 타입의 아티스트는 아니었습니다. 그래서 그녀가 직접 말하는 짧은 영상이나 인터뷰 자료는 팬들에게 더 특별하게 다가옵니다. 노래할 때의 목소리와는 또 다른, 조용하고 담백한 사람의 분위기가 느껴지는 자료들입니다.&lt;/p&gt;
&lt;div class=&quot;zard_video_area&quot;&gt;
&lt;div class=&quot;zard_video_grid&quot;&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;생전 영상 모음&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/j5uIHQfHsJ4?si=I_0lJWWmkb0qrpmh&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미의 생전 모습을 다시 볼 수 있는 영상 모음입니다. 노래 속 목소리와 사진으로만 기억하던 그녀의 분위기를 조금 더 가까이 느낄 수 있는 자료입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;짧게 말하는 사카이 이즈미&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/g6CpCyFWTB0?si=rsf3hxQRrIpRAjHr&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미가 짧게 말하는 모습이 담긴 영상입니다. 노래에서 느껴지는 차분함과는 또 다른, 실제 사람의 온도가 조용히 전해지는 자료입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;말하는 모습이 담긴 영상&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/RTbYt_9274A?si=k2atVVj_hyVYi_oU&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미가 말하는 모습이 담긴 짧은 영상입니다. 팬들이 왜 그녀의 노래뿐 아니라 말투와 분위기까지 오래 기억하는지 느낄 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1993년 2월 5일 일본 음악 방송 인터뷰&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/MKj4FzAr8DU?si=RIroaXzElVnC_yBM&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1993년 2월 5일 일본 음악 방송에서 인터뷰하는 사카이 이즈미의 모습이 담긴 영상입니다. 대중 앞에 자주 모습을 드러내지 않았던 아티스트였기에, 이런 인터뷰 영상은 더 소중한 기록처럼 느껴집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1992년 일본 방송 인터뷰&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/kJwWpd57-ZU?si=J1vMS4IO3pi8u2Tt&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1992년 일본 방송에서 인터뷰 중인 사카이 이즈미의 모습입니다. ZARD 초창기의 분위기와 그녀의 조심스러운 말투를 함께 볼 수 있는 귀한 자료입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가라오케 퀸 시절로 알려진 영상&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/Ja_ac06KzfQ?si=NqnbfcU0HB7bYxlO&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사카이 이즈미의 이른 시절 모습으로 알려진 영상입니다. 훗날 ZARD의 목소리로 오래 기억될 사람이 어떤 시간을 지나왔는지 생각하게 만드는 자료입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;zard_video_card&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;카페에 있는 사카이 이즈미의 모습&lt;/h3&gt;
&lt;div class=&quot;zard_video_embed&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/Ll28hM7DYes?si=i0MooN9g1O8-qtRb&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카페에 있는 사카이 이즈미의 모습이 담긴 영상입니다. 무대 위의 스타라기보다 조용한 한 사람의 분위기가 느껴져, 오히려 더 오래 마음에 남습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ZARD의 노래가 아직도 현재형으로 들리는 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 노래는 발표된 시점에만 머물지만, 어떤 노래는 시간이 흐르며 더 깊어집니다. ZARD의 노래는 후자에 가깝습니다. 처음에는 멜로디가 먼저 들렸다면, 시간이 지나고 나서는 사카이 이즈미의 목소리와 가사의 온도가 더 크게 다가왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그녀의 목소리에는 이상한 담백함이 있습니다. 화려하게 꾸미기보다 있는 그대로의 감정을 조용히 전하는 힘이 있습니다. 그래서 ZARD의 노래는 기쁠 때도, 지쳤을 때도, 무언가를 다시 시작하고 싶을 때도 다르게 들립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5월 27일은 분명 슬픈 날입니다. 하지만 동시에 감사한 날이기도 합니다. 한 사람이 남긴 목소리가 이렇게 오랫동안 누군가의 삶에 머물 수 있다는 것, 그리고 그 목소리가 지금도 누군가에게 작은 용기가 되어주고 있다는 것을 다시 느끼게 해주는 날이기 때문입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_closing&quot;&gt;
&lt;p class=&quot;zard_final&quot; data-ke-size=&quot;size16&quot;&gt;사카이 이즈미는 떠났지만,&lt;br /&gt;ZARD의 노래는 아직 우리 곁에 있습니다.&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;br /&gt;당신의 목소리는 지금도 많은 사람들의 하루 안에서 살아 있습니다.&lt;/p&gt;
&lt;div class=&quot;zard_last_words&quot;&gt;어쩌면 그리움은 시간이 지나며 사라지는 것이 아니라,&lt;br /&gt;익숙한 멜로디를 만날 때마다 다시 조용히 피어나는 마음인지도 모르겠습니다.&lt;br /&gt;오늘도 노래가 시작되면, 우리는 잠시 그 시절의 바람 속에서 사카이 이즈미를 다시 만납니다. &lt;span class=&quot;jp&quot;&gt; 坂井泉水さん、あなたの歌声は今も静かに心の中で生き続けています。 &lt;/span&gt; &lt;span class=&quot;en&quot;&gt; Your voice has not faded. It still remains softly in the hearts of those who listen. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;zard_signature&quot;&gt;오딘박스 최영환 &amp;middot; OdinBOX Choe Yeong Hwan&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;zard_sources&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고 자료&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://wezard.net/biography/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ZARD Official Website - Biography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kotobank.jp/word/%E5%9D%82%E4%BA%95%E6%B3%89%E6%B0%B4-3236286&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;コトバンク - 坂井泉水 プロフィール&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.oricon.co.jp/news/44979/full/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ORICON NEWS - ZARD坂井泉水さん、不慮の事故で死去&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.uta-net.com/song/8660/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Uta-Net - FIELD OF VIEW 「突然」 곡 정보&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wezard.net/35th/forever-moment/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ZARD 35th Anniversary - What a beautiful memory 〜forever moment〜&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://odinbox.co.kr/535&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;오딘박스 기존 글 - 자드(ZARD), 사카이 이즈미&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;zard_seo_keywords&quot;&gt;이 글은 ZARD, 자드, 사카이 이즈미, 坂井泉水, さかい いずみ, Izumi Sakai, Sakai Izumi, 본명 蒲池幸子, 蒲池 幸子, かまち さちこ, Sachiko Kamachi, Kamachi Sachiko, ZARD 追悼, ZARD Tribute, 5月27日 命日, 5월 27일, 負けないで, 心を開いて, 揺れる想い, 突然, 眠れない夜を抱いて, 사카이 이즈미 인터뷰, 坂井泉水 インタビュー, 1993년 ZARD 라이브, ZARD 뉴스, 사카이 이즈미 묘소를 중심으로 정리한 개인 추모 글입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;/main&gt;&lt;/article&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>5월27일</category>
      <category>90년대jpop</category>
      <category>IzumiSakai</category>
      <category>ZARD</category>
      <category>ZARD추모</category>
      <category>坂井泉水</category>
      <category>心を開いて</category>
      <category>負けないで</category>
      <category>사카이이즈미</category>
      <category>자드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/587</guid>
      <comments>https://odinbox.tistory.com/587#entry587comment</comments>
      <pubDate>Wed, 27 May 2026 00:21:05 +0900</pubDate>
    </item>
    <item>
      <title>웹페이지 캐시 완전 정리, Cache-Control부터 브라우저 캐시, CDN 캐시까지</title>
      <link>https://odinbox.tistory.com/586</link>
      <description>&lt;!--
SEO 제목 후보
1. 웹페이지 캐시 완전 정리 : Cache-Control부터 브라우저 캐시, CDN 캐시까지
2. 웹 캐시 설정 방법 총정리 : no-cache, no-store, ETag, CDN 캐시 이해하기
3. 웹페이지 캐시 때문에 화면이 안 바뀔 때 : 원리부터 해결 방법까지

최종 추천 글제목
웹페이지 캐시 완전 정리 : Cache-Control부터 브라우저 캐시, CDN 캐시까지

추천 검색 설명
웹페이지 캐시의 원리부터 Cache-Control, no-cache와 no-store 차이, ETag, CDN 캐시, Nginx 설정, fetch 캐시 옵션까지 실무 중심으로 정리한 웹 성능 최적화 가이드입니다.

추천 URL 슬러그
web-cache-cache-control-browser-cdn-guide

썸네일 제목
웹 캐시 완전 정리

썸네일 서브 문구
Cache-Control · 브라우저 캐시 · CDN 캐시
--&gt;
&lt;div class=&quot;webcache_article&quot;&gt;
&lt;style&gt;
    .webcache_article {
      max-width: 980px;
      margin: 0 auto;
      padding: 10px 0 40px;
      font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans KR&quot;, Arial, sans-serif;
      color: #1f2937;
      line-height: 1.85;
      word-break: keep-all;
    }

    .webcache_article * {
      box-sizing: border-box;
    }

    .webcache_article a {
      color: #2563eb;
      text-decoration: none;
      border-bottom: 1px solid rgba(37, 99, 235, 0.3);
    }

    .webcache_article a:hover {
      border-bottom-color: #2563eb;
    }

    .webcache_thumbnail {
      margin: 8px auto 28px;
      text-align: center;
    }

    .webcache_thumbnail p {
      margin: 0;
    }

    .webcache_thumbnail_caption {
      margin-top: 10px;
      color: #6b7280;
      font-size: 13px;
      line-height: 1.6;
    }

    .webcache_hero {
      margin: 20px 0 36px;
      padding: 38px 34px;
      border-radius: 28px;
      background:
        radial-gradient(circle at top left, rgba(37, 99, 235, 0.18), transparent 34%),
        linear-gradient(135deg, #eff6ff 0%, #f8fafc 50%, #fff7ed 100%);
      border: 1px solid #dbeafe;
      box-shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
    }

    .webcache_eyebrow {
      display: inline-block;
      margin-bottom: 14px;
      padding: 7px 13px;
      border-radius: 999px;
      background: #2563eb;
      color: #ffffff;
      font-size: 13px;
      font-weight: 800;
      letter-spacing: -0.2px;
    }

    .webcache_title {
      margin: 0 0 16px;
      color: #111827;
      font-size: 34px;
      line-height: 1.28;
      letter-spacing: -1.2px;
    }

    .webcache_subtitle {
      margin: 0;
      color: #4b5563;
      font-size: 17px;
    }

    .webcache_meta {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 18px;
    }

    .webcache_meta span {
      display: inline-block;
      padding: 6px 10px;
      border-radius: 999px;
      background: rgba(255, 255, 255, 0.72);
      border: 1px solid #dbeafe;
      color: #374151;
      font-size: 13px;
      font-weight: 700;
    }

    .webcache_section {
      margin: 42px 0;
      scroll-margin-top: 80px;
    }

    .webcache_section h2 {
      margin: 0 0 18px;
      padding-bottom: 10px;
      border-bottom: 2px solid #e5e7eb;
      color: #111827;
      font-size: 25px;
      line-height: 1.35;
      letter-spacing: -0.7px;
    }

    .webcache_section h3 {
      margin: 28px 0 12px;
      color: #1f2937;
      font-size: 20px;
      line-height: 1.45;
      letter-spacing: -0.4px;
    }

    .webcache_box {
      margin: 18px 0;
      padding: 20px 22px;
      border-radius: 18px;
      background: #f9fafb;
      border: 1px solid #e5e7eb;
    }

    .webcache_note {
      margin: 18px 0;
      padding: 20px 22px;
      border-radius: 18px;
      background: #eff6ff;
      border: 1px solid #bfdbfe;
      color: #1e3a8a;
    }

    .webcache_warn {
      margin: 18px 0;
      padding: 20px 22px;
      border-radius: 18px;
      background: #fff7ed;
      border: 1px solid #fed7aa;
      color: #7c2d12;
    }

    .webcache_good {
      margin: 18px 0;
      padding: 20px 22px;
      border-radius: 18px;
      background: #ecfdf5;
      border: 1px solid #a7f3d0;
      color: #064e3b;
    }

    .webcache_quote {
      margin: 22px 0;
      padding: 20px 22px;
      border-left: 5px solid #2563eb;
      background: #eff6ff;
      border-radius: 0 18px 18px 0;
      color: #1e3a8a;
      font-weight: 700;
    }

    .webcache_toc {
      margin: 28px 0;
      padding: 24px 24px;
      border-radius: 22px;
      background: #f8fafc;
      border: 1px solid #e5e7eb;
    }

    .webcache_toc strong {
      display: block;
      margin-bottom: 12px;
      color: #111827;
      font-size: 18px;
    }

    .webcache_toc ol {
      margin: 0;
      padding-left: 22px;
    }

    .webcache_toc li {
      margin: 7px 0;
    }

    .webcache_table_wrap {
      overflow-x: auto;
      margin: 18px 0;
      border-radius: 16px;
      border: 1px solid #e5e7eb;
    }

    .webcache_table {
      width: 100%;
      min-width: 720px;
      border-collapse: collapse;
      font-size: 15px;
    }

    .webcache_table th,
    .webcache_table td {
      padding: 13px 14px;
      border-bottom: 1px solid #e5e7eb;
      border-right: 1px solid #e5e7eb;
      vertical-align: top;
    }

    .webcache_table th:last-child,
    .webcache_table td:last-child {
      border-right: none;
    }

    .webcache_table tr:last-child td {
      border-bottom: none;
    }

    .webcache_table th {
      background: #f3f4f6;
      color: #111827;
      font-weight: 800;
    }

    .webcache_table td {
      background: #ffffff;
    }

    .webcache_code {
      margin: 16px 0;
      padding: 18px 20px;
      border-radius: 18px;
      background: #0f172a;
      color: #e5e7eb;
      overflow-x: auto;
      font-size: 14px;
      line-height: 1.65;
    }

    .webcache_code code {
      font-family: Consolas, Monaco, &quot;Courier New&quot;, monospace;
      white-space: pre;
    }

    .webcache_article code {
      padding: 2px 5px;
      border-radius: 6px;
      background: #f3f4f6;
      color: #be123c;
      font-family: Consolas, Monaco, &quot;Courier New&quot;, monospace;
      font-size: 0.92em;
    }

    .webcache_code code {
      padding: 0;
      background: transparent;
      color: inherit;
    }

    .webcache_list {
      margin: 0;
      padding-left: 22px;
    }

    .webcache_list li {
      margin: 8px 0;
    }

    .webcache_tagbox {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 12px;
    }

    .webcache_tag {
      display: inline-block;
      padding: 7px 11px;
      border-radius: 999px;
      background: #f3f4f6;
      border: 1px solid #e5e7eb;
      color: #374151;
      font-size: 13px;
      font-weight: 600;
    }

    .webcache_refs {
      margin: 0;
      padding-left: 22px;
    }

    .webcache_refs li {
      margin: 10px 0;
    }

    .webcache_faq_item {
      margin: 16px 0;
      padding: 20px 22px;
      border-radius: 18px;
      background: #ffffff;
      border: 1px solid #e5e7eb;
      box-shadow: 0 10px 28px rgba(15, 23, 42, 0.04);
    }

    .webcache_faq_item h3 {
      margin-top: 0;
    }

    @media (max-width: 640px) {
      .webcache_hero {
        padding: 28px 22px;
        border-radius: 22px;
      }

      .webcache_title {
        font-size: 27px;
      }

      .webcache_section h2 {
        font-size: 22px;
      }

      .webcache_section h3 {
        font-size: 18px;
      }

      .webcache_article {
        line-height: 1.78;
      }
    }
  &lt;/style&gt;
&lt;article&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;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgB7S2/dJMcaaZG83a/E9TotbLHDKEHl26HkvD5A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgB7S2/dJMcaaZG83a/E9TotbLHDKEHl26HkvD5A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgB7S2/dJMcaaZG83a/E9TotbLHDKEHl26HkvD5A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgB7S2%2FdJMcaaZG83a%2FE9TotbLHDKEHl26HkvD5A1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;figure class=&quot;webcache_thumbnail&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figcaption class=&quot;webcache_thumbnail_caption&quot;&gt;웹페이지 캐시, Cache-Control, 브라우저 캐시, CDN 캐시를 한 번에 이해하기 위한 실무 가이드입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div class=&quot;webcache_hero&quot;&gt;웹페이지 캐시는 브라우저 캐시, CDN 캐시, 프록시 캐시, 서비스 워커 캐시가 함께 동작하는 웹 성능 최적화 기술입니다. 이 글에서는 Cache-Control, no-cache와 no-store 차이, ETag, Last-Modified, Vary, Nginx 캐시 설정, fetch 캐시 옵션까지 실무 중심으로 정리합니다.&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;section id=&quot;seo-summary&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글에서 다루는 내용&lt;/h2&gt;
&lt;div class=&quot;webcache_note&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 웹페이지 캐시 설정 방법을 찾는 개발자를 위해 작성했습니다. 단순히 &amp;ldquo;캐시 삭제하는 법&amp;rdquo;이 아니라, 브라우저 캐시와 CDN 캐시가 어떻게 동작하는지, &lt;code&gt;Cache-Control&lt;/code&gt; 옵션을 어떤 상황에서 어떻게 써야 하는지, 배포 후 오래된 CSS와 JavaScript가 남는 문제를 어떻게 줄일 수 있는지까지 정리합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;webcache_toc&quot;&gt;&lt;b&gt;목차&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#intro&quot;&gt;캐시는 쉽지만, 제대로 쓰기는 어렵다&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#where-cache&quot;&gt;웹 캐시는 어디에 저장될까?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#http-cache-basic&quot;&gt;HTTP 캐시의 핵심 개념&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#cache-control&quot;&gt;Cache-Control 옵션 정리&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#cache-strategy&quot;&gt;상황별 추천 캐시 전략&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#server-config&quot;&gt;서버별 캐시 설정 예시&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#fetch-cache&quot;&gt;프론트엔드 fetch 캐시 옵션&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#etag-vary&quot;&gt;ETag, Last-Modified, Vary 이해하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#debug-cache&quot;&gt;개발 중 캐시 문제 확인 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#mistakes&quot;&gt;실무에서 많이 하는 캐시 실수&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#recommend-table&quot;&gt;상황별 캐시 정책 추천표&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#faq&quot;&gt;자주 묻는 질문&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#refs&quot;&gt;참고자료 : 공식문서&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;intro&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;캐시는 쉽지만, 제대로 쓰기는 어렵다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지 캐시는 사이트 속도를 빠르게 만들고 서버 비용을 줄이는 핵심 기술입니다. 하지만 &lt;code&gt;Cache-Control&lt;/code&gt;, 브라우저 캐시, CDN 캐시, ETag, 서비스 워커 캐시가 섞이면 문제를 찾기 어려워집니다. 특히 CSS를 수정했는데 화면이 바뀌지 않거나, JavaScript 배포 후 일부 사용자에게만 오류가 발생하는 문제는 대부분 캐시 전략과 관련이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 개발을 하다 보면 한 번쯤 이런 상황을 만납니다.&lt;/p&gt;
&lt;div class=&quot;webcache_box&quot;&gt;
&lt;ul class=&quot;webcache_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CSS를 수정했는데 사용자는 여전히 예전 화면을 보고 있다.&lt;/li&gt;
&lt;li&gt;JavaScript 파일을 배포했는데 일부 사용자에게만 오류가 난다.&lt;/li&gt;
&lt;li&gt;API 응답은 바뀌었는데 브라우저나 CDN에서 예전 데이터를 보여준다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;no-cache&lt;/code&gt;를 넣었는데도 캐시가 저장되는 것처럼 보인다.&lt;/li&gt;
&lt;li&gt;개발 환경에서는 정상인데 운영 배포 후 특정 사용자만 화면이 깨진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시는 속도를 올리는 강력한 기술입니다. 하지만 잘못 설정하면 &amp;ldquo;빠른 성능 최적화&amp;rdquo;가 아니라 &amp;ldquo;오래된 오류를 빠르게 재사용하는 장치&amp;rdquo;가 될 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20년 차 개발자 관점에서 캐시를 설명하자면, 캐시는 냉장고와 비슷합니다. 음식을 매번 새로 만들지 않고 보관해두면 빠르고 편합니다. 하지만 유통기한, 보관 위치, 누가 먹어도 되는 음식인지가 정리되어 있지 않으면 문제가 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 캐시도 마찬가지입니다. 어떤 파일은 오래 보관해도 되고, 어떤 응답은 매번 확인해야 하며, 어떤 데이터는 아예 저장하면 안 됩니다. 좋은 캐시 전략은 &amp;ldquo;무조건 캐시하기&amp;rdquo;도 아니고 &amp;ldquo;무조건 캐시 막기&amp;rdquo;도 아닙니다. 중요한 것은 리소스 성격에 맞게 다르게 제어하는 것입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;where-cache&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;웹 캐시는 어디에 저장될까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지 캐시는 한 곳에만 존재하지 않습니다. 실제 운영 환경에서는 여러 계층의 캐시가 동시에 관여합니다.&lt;/p&gt;
&lt;div class=&quot;webcache_table_wrap&quot;&gt;
&lt;table class=&quot;webcache_table&quot; 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;주의할 점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;브라우저 캐시&lt;/td&gt;
&lt;td&gt;사용자 PC나 모바일 브라우저에 저장되는 캐시입니다. 이미지, CSS, JS, 폰트 등이 주로 저장됩니다.&lt;/td&gt;
&lt;td&gt;사용자 기기에 저장되므로 서버에서 즉시 삭제하기 어렵습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN 캐시&lt;/td&gt;
&lt;td&gt;Cloudflare, CloudFront, Fastly 같은 CDN 엣지 서버에 저장되는 캐시입니다.&lt;/td&gt;
&lt;td&gt;여러 사용자에게 같은 응답이 재사용될 수 있으므로 개인정보 응답은 매우 조심해야 합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;프록시 캐시&lt;/td&gt;
&lt;td&gt;회사망, 통신사, 리버스 프록시, Nginx 같은 중간 서버에서 저장될 수 있는 캐시입니다.&lt;/td&gt;
&lt;td&gt;응답 헤더가 의도와 다르면 예상하지 못한 공유 캐시가 생길 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서비스 워커 캐시&lt;/td&gt;
&lt;td&gt;PWA나 오프라인 앱에서 JavaScript로 직접 제어하는 캐시입니다.&lt;/td&gt;
&lt;td&gt;HTTP 캐시보다 더 강하게 개입할 수 있어 업데이트 전략을 잘못 잡으면 오래된 앱이 계속 남을 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Back/Forward Cache&lt;/td&gt;
&lt;td&gt;브라우저의 뒤로가기, 앞으로가기를 빠르게 하기 위해 페이지 상태 자체를 보존하는 최적화입니다.&lt;/td&gt;
&lt;td&gt;일반 HTTP 캐시와 다릅니다. 폼 화면, 로그인 화면, 결제 화면에서는 동작을 신중히 확인해야 합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;webcache_quote&quot;&gt;캐시 문제를 해결할 때 가장 먼저 해야 할 일은 &amp;ldquo;어디에 캐시되어 있는가?&amp;rdquo;를 찾는 것입니다. 브라우저인지, CDN인지, 서버 프록시인지, 서비스 워커인지에 따라 해결 방법이 완전히 달라집니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;http-cache-basic&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;HTTP 캐시의 핵심 개념&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Fresh와 Stale&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시된 응답은 크게 두 상태로 나눌 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_table_wrap&quot;&gt;
&lt;table class=&quot;webcache_table&quot; 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;예시&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fresh&lt;/td&gt;
&lt;td&gt;아직 유효기간이 남아 있어 서버에 다시 묻지 않고 바로 재사용할 수 있는 상태입니다.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: max-age=3600&lt;/code&gt; 설정 후 1시간 이내&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stale&lt;/td&gt;
&lt;td&gt;유효기간이 지나서 서버에 다시 확인해야 하는 상태입니다.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;max-age&lt;/code&gt; 시간이 지난 CSS, JS, 이미지, API 응답&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은 stale 상태가 되었다고 해서 캐시가 바로 삭제되는 것은 아니라는 점입니다. 캐시는 남아 있을 수 있고, 서버에 재검증한 뒤 계속 사용할 수도 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Revalidation&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재검증은 브라우저가 서버에게 &amp;ldquo;내가 가진 파일이 아직 최신인가요?&amp;rdquo;라고 물어보는 과정입니다. 이때 서버가 변경 없음이라고 판단하면 전체 파일을 다시 내려주지 않고 &lt;code&gt;304 Not Modified&lt;/code&gt;를 응답합니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;브라우저 : /app.js 파일 주세요. 제가 가진 ETag는 &quot;abc123&quot;입니다.
서버 : 아직 그대로입니다. 304 Not Modified
브라우저 : 그러면 기존 캐시 파일을 계속 사용하겠습니다.&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조 덕분에 캐시는 빠르면서도 트래픽을 줄일 수 있습니다. 파일 전체를 다시 받지 않고 변경 여부만 확인하기 때문입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Cache Key&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시는 보통 요청 메서드와 URL을 기준으로 응답을 구분합니다. 그래서 아래 주소들은 사람이 보기에는 비슷해도 캐시 입장에서는 서로 다른 리소스로 판단될 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;/assets/app.css
/assets/app.css?v=20260523
/assets/app.8fd2a1.css&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 원리를 이용해 파일 내용이 바뀔 때 파일명이나 쿼리스트링을 바꾸는 방식을 캐시 버스팅이라고 부릅니다. 실무에서는 쿼리스트링보다 빌드 결과물에 해시가 들어간 파일명을 쓰는 방식이 더 안정적입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;cache-control&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Cache-Control 옵션 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 제어의 중심은 &lt;code&gt;Cache-Control&lt;/code&gt; 헤더입니다. 여러 옵션을 콤마로 조합해서 사용할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: public, max-age=31536000, immutable&lt;/code&gt;&lt;/div&gt;
&lt;div class=&quot;webcache_table_wrap&quot;&gt;
&lt;table class=&quot;webcache_table&quot; 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;추천 상황&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max-age=초&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;지정한 초 동안 캐시를 fresh 상태로 봅니다.&lt;/td&gt;
&lt;td&gt;이미지, CSS, JS, 폰트 등 변경 주기가 명확한 정적 파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s-maxage=초&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CDN, 프록시 같은 공유 캐시에 적용되는 유효기간입니다.&lt;/td&gt;
&lt;td&gt;브라우저 캐시와 CDN 캐시 시간을 다르게 제어하고 싶을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;public&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브라우저뿐 아니라 CDN 같은 공유 캐시도 저장할 수 있습니다.&lt;/td&gt;
&lt;td&gt;모든 사용자에게 동일한 이미지, CSS, JS, 공개 API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;private&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;사용자 브라우저 같은 private cache에만 저장하도록 합니다.&lt;/td&gt;
&lt;td&gt;로그인 후 사용자별 화면, 개인화 응답&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-cache&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;저장은 가능하지만 재사용 전 반드시 서버에 재검증해야 합니다.&lt;/td&gt;
&lt;td&gt;HTML, 자주 바뀌는 API, 최신성이 중요한 화면&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-store&lt;/code&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;code&gt;must-revalidate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;만료된 캐시를 사용할 때 반드시 서버 재검증을 요구합니다.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;max-age&lt;/code&gt;와 함께 엄격한 만료 정책이 필요할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;immutable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;fresh 상태인 동안 파일이 바뀌지 않는다고 알려줍니다.&lt;/td&gt;
&lt;td&gt;파일명에 해시가 붙은 정적 파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stale-while-revalidate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;만료된 캐시를 일단 보여주고 백그라운드에서 새 응답을 갱신할 수 있게 합니다.&lt;/td&gt;
&lt;td&gt;약간 오래된 데이터가 보여도 괜찮은 공개 API, 목록, 랭킹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stale-if-error&lt;/code&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;code&gt;no-transform&lt;/code&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;div class=&quot;webcache_warn&quot;&gt;&lt;b&gt;중요 : &lt;/b&gt; &lt;code&gt;no-cache&lt;/code&gt;는 &amp;ldquo;캐시하지 마라&amp;rdquo;가 아닙니다. 저장은 될 수 있지만, 다시 사용할 때 서버에 확인하라는 의미입니다. 정말 저장 자체를 막고 싶다면 &lt;code&gt;no-store&lt;/code&gt;를 사용해야 합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;cache-strategy&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상황별 추천 캐시 전략&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. HTML 문서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML은 보통 웹앱의 진입점입니다. HTML이 오래 캐시되면 새로 배포한 JS, CSS 파일을 참조하지 못해 배포 후 화면이 깨질 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_good&quot;&gt;&lt;b&gt;추천 설정 : &lt;/b&gt; HTML은 &lt;code&gt;no-cache&lt;/code&gt;로 저장은 허용하되, 매번 서버에 최신 여부를 확인하게 하는 방식이 안전합니다.&lt;/div&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: no-cache&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자 페이지, 결제 페이지, 개인정보 페이지처럼 민감도가 높은 화면이라면 저장 자체를 막는 편이 낫습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: no-store&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 해시가 붙은 CSS, JS, 이미지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 결과물이 아래처럼 파일명에 해시를 포함한다면 강한 캐시를 걸어도 안전합니다. 파일 내용이 바뀌면 파일명도 바뀌기 때문입니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;/assets/app.a82f91c3.js
/assets/style.0d9a7f21.css
/assets/logo.4c11e92a.webp&lt;/code&gt;&lt;/div&gt;
&lt;div class=&quot;webcache_good&quot;&gt;&lt;b&gt;추천 설정 : &lt;/b&gt; 해시가 붙은 정적 파일은 1년 캐시와 &lt;code&gt;immutable&lt;/code&gt; 조합이 좋습니다.&lt;/div&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: public, max-age=31536000, immutable&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 이 전략은 &amp;ldquo;파일명이 바뀐다&amp;rdquo;는 전제가 있어야 합니다. &lt;code&gt;/app.js&lt;/code&gt;처럼 같은 URL의 내용만 계속 바꾸는 파일에 1년 캐시를 걸면 사용자는 오래된 파일을 계속 볼 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 해시가 없는 CSS, JS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 해시를 쓰지 못하고 같은 파일명으로 계속 덮어쓰는 구조라면 긴 &lt;code&gt;max-age&lt;/code&gt;는 위험합니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: no-cache&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 아주 짧은 캐시를 줄 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: public, max-age=60, must-revalidate&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 공개 API&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게시글 목록, 상품 목록, 공지사항 목록처럼 모든 사용자에게 거의 동일하게 보이는 API는 짧은 캐시를 활용할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: public, max-age=60, stale-while-revalidate=300&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설정은 60초 동안은 캐시를 바로 사용하고, 이후 300초 동안은 오래된 응답을 먼저 보여주면서 백그라운드 갱신을 허용하는 방식입니다. 목록성 데이터, 인기글, 랭킹, 공지 목록처럼 약간의 지연이 허용되는 곳에 적합합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 로그인 사용자 API&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이페이지, 내 주문내역, 내 알림, 내 운동 기록처럼 사용자별 데이터는 공유 캐시에 들어가면 안 됩니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: private, no-cache&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인정보, 인증 토큰, 결제, 민감 데이터라면 더 강하게 막습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: no-store&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. CDN을 사용하는 경우&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDN을 사용하면 브라우저 캐시와 CDN 캐시를 분리해서 생각해야 합니다. 예를 들어 브라우저에는 매번 확인하게 하고, CDN에는 10분 정도 저장하게 만들 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Cache-Control: no-cache, s-maxage=600, stale-while-revalidate=60&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 원본 서버 부하를 줄이면서도 브라우저 쪽에서는 비교적 최신성을 유지하고 싶을 때 사용할 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;server-config&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;서버별 캐시 설정 예시&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Nginx 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nginx에서는 &lt;code&gt;add_header&lt;/code&gt;와 &lt;code&gt;expires&lt;/code&gt; 지시어를 이용해 응답 헤더를 제어할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;server {
    listen 80;
    server_name example.com;

    location / {
        try_files $uri $uri/ /index.html;
        add_header Cache-Control &quot;no-cache&quot; always;
    }

    location ~* \.(?:js|css|png|jpg|jpeg|gif|webp|svg|ico|woff2?)$ {
        expires 1y;
        add_header Cache-Control &quot;public, max-age=31536000, immutable&quot; always;
        access_log off;
    }
}&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 HTML과 정적 리소스를 다르게 보는 것입니다. &lt;code&gt;index.html&lt;/code&gt;은 앱의 입구이므로 최신 확인을 하게 하고, 해시가 붙은 JS/CSS/이미지 파일은 오래 캐시합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Apache 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apache에서는 &lt;code&gt;mod_expires&lt;/code&gt;로 만료 시간을 제어하고, &lt;code&gt;mod_headers&lt;/code&gt;의 &lt;code&gt;Header&lt;/code&gt; 지시어로 응답 헤더를 직접 설정할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;&amp;lt;IfModule mod_expires.c&amp;gt;
    ExpiresActive On

    ExpiresByType text/css &quot;access plus 1 year&quot;
    ExpiresByType application/javascript &quot;access plus 1 year&quot;
    ExpiresByType image/png &quot;access plus 1 year&quot;
    ExpiresByType image/jpeg &quot;access plus 1 year&quot;
    ExpiresByType image/webp &quot;access plus 1 year&quot;
    ExpiresByType image/svg+xml &quot;access plus 1 year&quot;
&amp;lt;/IfModule&amp;gt;

&amp;lt;IfModule mod_headers.c&amp;gt;
    &amp;lt;FilesMatch &quot;\.(css|js|png|jpg|jpeg|webp|svg|woff2?)$&quot;&amp;gt;
        Header set Cache-Control &quot;public, max-age=31536000, immutable&quot;
    &amp;lt;/FilesMatch&amp;gt;

    &amp;lt;FilesMatch &quot;\.(html)$&quot;&amp;gt;
        Header set Cache-Control &quot;no-cache&quot;
    &amp;lt;/FilesMatch&amp;gt;
&amp;lt;/IfModule&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Node.js Express 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React, Vue, Vite, Angular 같은 프론트엔드 빌드 결과물을 Express에서 제공한다면 아래처럼 정적 파일과 HTML을 나눠서 처리할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;import express from &quot;express&quot;;
import path from &quot;path&quot;;

const app = express();

app.use(&quot;/assets&quot;, express.static(path.join(process.cwd(), &quot;dist/assets&quot;), {
  immutable: true,
  maxAge: &quot;1y&quot;
}));

app.get(&quot;*&quot;, (req, res) =&amp;gt; {
  res.setHeader(&quot;Cache-Control&quot;, &quot;no-cache&quot;);
  res.sendFile(path.join(process.cwd(), &quot;dist/index.html&quot;));
});

app.listen(3000);&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. API 응답 예시&lt;/h3&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;// 공개 목록 API
res.setHeader(&quot;Cache-Control&quot;, &quot;public, max-age=60, stale-while-revalidate=300&quot;);

// 로그인 사용자 API
res.setHeader(&quot;Cache-Control&quot;, &quot;private, no-cache&quot;);

// 결제, 인증, 개인정보 API
res.setHeader(&quot;Cache-Control&quot;, &quot;no-store&quot;);&lt;/code&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;fetch-cache&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프론트엔드 fetch 옵션으로 캐시 제어하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 응답 헤더가 캐시 정책의 중심이지만, 프론트엔드에서도 &lt;code&gt;fetch&lt;/code&gt; 옵션으로 요청 캐시 동작을 어느 정도 제어할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_table_wrap&quot;&gt;
&lt;table class=&quot;webcache_table&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;fetch cache 옵션&lt;/th&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;&lt;code&gt;default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브라우저 기본 HTTP 캐시 정책을 따릅니다.&lt;/td&gt;
&lt;td&gt;일반적인 요청&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-store&lt;/code&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;code&gt;reload&lt;/code&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;code&gt;no-cache&lt;/code&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;code&gt;force-cache&lt;/code&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;code&gt;only-if-cached&lt;/code&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;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;// 사용자별 민감 데이터
const me = await fetch(&quot;/api/me&quot;, {
  cache: &quot;no-store&quot;
});

// 최신 여부를 확인하고 싶은 데이터
const notice = await fetch(&quot;/api/notice&quot;, {
  cache: &quot;no-cache&quot;
});

// 캐시가 있으면 우선 사용해도 되는 데이터
const guide = await fetch(&quot;/api/guide&quot;, {
  cache: &quot;force-cache&quot;
});&lt;/code&gt;&lt;/div&gt;
&lt;div class=&quot;webcache_warn&quot;&gt;&lt;b&gt;주의 : &lt;/b&gt; 프레임워크마다 &lt;code&gt;fetch&lt;/code&gt; 캐시 해석이 다를 수 있습니다. 특히 Next.js 같은 프레임워크는 브라우저 HTTP 캐시, 서버 데이터 캐시, 라우트 캐시, 렌더링 캐시가 별도로 존재할 수 있으므로 공식 문서를 기준으로 확인해야 합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;etag-vary&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ETag, Last-Modified, Vary 이해하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. ETag&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ETag&lt;/code&gt;는 특정 리소스 버전을 식별하는 값입니다. 서버는 응답에 ETag를 내려주고, 브라우저는 다음 요청에서 이 값을 이용해 &amp;ldquo;내가 가진 리소스가 아직 최신인지&amp;rdquo; 확인할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;ETag: &quot;33a64df551425fcc55e4d42a148795d9f25f89d4&quot;&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 브라우저는 조건부 요청을 보낼 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;If-None-Match: &quot;33a64df551425fcc55e4d42a148795d9f25f89d4&quot;&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 변경 없음으로 판단하면 &lt;code&gt;304 Not Modified&lt;/code&gt;를 응답하고, 브라우저는 기존 캐시를 재사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Last-Modified&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Last-Modified&lt;/code&gt;는 리소스가 마지막으로 수정된 시간을 나타냅니다. 정적 파일 서버에서는 파일 수정 시간을 기준으로 자동 설정되는 경우가 많습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Last-Modified: Wed, 22 May 2026 10:00:00 GMT&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Vary&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Vary&lt;/code&gt;는 같은 URL이라도 어떤 요청 헤더에 따라 응답이 달라지는지 캐시에 알려주는 헤더입니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;Vary: Accept-Encoding
Vary: Accept-Language
Vary: User-Agent&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 &lt;code&gt;Vary: Accept-Language&lt;/code&gt;가 있으면 같은 URL이라도 한국어 요청과 영어 요청을 다른 응답으로 캐시할 수 있습니다. 다만 &lt;code&gt;Vary&lt;/code&gt;를 너무 넓게 사용하면 캐시 조각이 많아져 캐시 효율이 떨어질 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;debug-cache&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개발 중 캐시 문제를 확인하는 방법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Chrome DevTools Network 탭 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크롬 개발자 도구의 Network 탭에서 각 요청을 클릭하면 응답 헤더를 확인할 수 있습니다. 다음 항목을 특히 봐야 합니다.&lt;/p&gt;
&lt;div class=&quot;webcache_box&quot;&gt;
&lt;ul class=&quot;webcache_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Cache-Control&lt;/code&gt; : 캐시 정책&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ETag&lt;/code&gt; : 파일 버전 식별자&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Last-Modified&lt;/code&gt; : 마지막 수정 시간&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Age&lt;/code&gt; : 공유 캐시에서 얼마나 오래 있었는지&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CF-Cache-Status&lt;/code&gt;, &lt;code&gt;X-Cache&lt;/code&gt; : CDN 캐시 HIT/MISS 여부&lt;/li&gt;
&lt;li&gt;Status Code : &lt;code&gt;200&lt;/code&gt;인지 &lt;code&gt;304&lt;/code&gt;인지&lt;/li&gt;
&lt;li&gt;Size : &lt;code&gt;from disk cache&lt;/code&gt;, &lt;code&gt;from memory cache&lt;/code&gt; 여부&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Disable cache&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Chrome DevTools의 Network 탭에는 &lt;code&gt;Disable cache&lt;/code&gt; 옵션이 있습니다. 개발 중에는 이 옵션을 켜고 테스트하면 브라우저 캐시 영향을 줄일 수 있습니다. 단, 이 옵션은 DevTools가 열려 있을 때의 테스트 용도라는 점을 기억해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Hard Reload와 Empty Cache and Hard Reload&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자 도구를 연 상태에서 새로고침 버튼을 길게 누르거나 우클릭하면 다음 옵션을 볼 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_table_wrap&quot;&gt;
&lt;table class=&quot;webcache_table&quot; 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;Normal Reload&lt;/td&gt;
&lt;td&gt;일반 새로고침입니다. 캐시 정책에 따라 재사용 또는 재검증합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Reload&lt;/td&gt;
&lt;td&gt;페이지 로드에 필요한 리소스를 강제로 다시 요청합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty Cache and Hard Reload&lt;/td&gt;
&lt;td&gt;해당 페이지 관련 캐시를 비우고 강제로 다시 요청합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 그래도 예전 파일이 보인다면&lt;/h3&gt;
&lt;div class=&quot;webcache_warn&quot;&gt;
&lt;ul class=&quot;webcache_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저 캐시가 아니라 CDN 캐시일 수 있습니다.&lt;/li&gt;
&lt;li&gt;서비스 워커가 응답을 가로채고 있을 수 있습니다.&lt;/li&gt;
&lt;li&gt;DevTools Local Overrides가 켜져 있을 수 있습니다.&lt;/li&gt;
&lt;li&gt;서버 앞단의 Nginx, 프록시, WAS 캐시가 남아 있을 수 있습니다.&lt;/li&gt;
&lt;li&gt;파일명 해시가 바뀌지 않아 브라우저가 같은 파일로 판단하고 있을 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;mistakes&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무에서 많이 하는 캐시 실수&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실수 1. 모든 파일에 no-store를 넣는다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 최신성 문제는 줄어들 수 있지만 성능은 크게 떨어집니다. 이미지, 폰트, JS, CSS를 매번 다시 받으면 사용자 경험도 나빠지고 서버 비용도 증가합니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;# 좋지 않은 예시
Cache-Control: no-store&lt;/code&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 파일은 가능하면 파일명 해시를 붙이고 강하게 캐시하는 것이 좋습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;# 좋은 예시
Cache-Control: public, max-age=31536000, immutable&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실수 2. HTML까지 1년 캐시한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPA에서 &lt;code&gt;index.html&lt;/code&gt;을 오래 캐시하면 새 배포 후에도 사용자가 예전 JS 파일을 계속 참조할 수 있습니다. 이 경우 일부 사용자에게만 흰 화면, JS 오류, CSS 깨짐이 나타날 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;webcache_code&quot;&gt;&lt;code&gt;# HTML에는 보통 이쪽이 안전합니다.
Cache-Control: no-cache&lt;/code&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실수 3. no-cache를 캐시 금지로 오해한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;no-cache&lt;/code&gt;는 저장을 막지 않습니다. 재사용 전 서버에 확인하라는 의미입니다. 저장 자체를 막으려면 &lt;code&gt;no-store&lt;/code&gt;가 필요합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실수 4. CDN 캐시와 브라우저 캐시를 같은 것으로 본다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저 캐시는 사용자 기기에 있고, CDN 캐시는 사용자와 서버 사이의 엣지 서버에 있습니다. CDN은 여러 사용자에게 같은 캐시를 제공할 수 있으므로 개인정보 응답이 들어가면 큰 사고가 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실수 5. 서비스 워커 캐시를 잊는다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PWA를 적용한 사이트라면 서비스 워커가 네트워크 요청을 가로챌 수 있습니다. 서버 헤더를 아무리 바꿔도 서비스 워커가 예전 응답을 반환하고 있으면 사용자는 계속 오래된 화면을 보게 됩니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;recommend-table&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상황별 캐시 정책 추천표&lt;/h2&gt;
&lt;div class=&quot;webcache_table_wrap&quot;&gt;
&lt;table class=&quot;webcache_table&quot; 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;이유&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;일반 HTML&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: no-cache&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;저장은 가능하지만 매번 최신 여부를 확인하게 합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;관리자 HTML&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: no-store&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;민감 정보나 권한 화면은 저장 자체를 막는 편이 안전합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;해시가 붙은 JS/CSS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: public, max-age=31536000, immutable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;파일명 변경으로 새 버전을 구분할 수 있으므로 오래 캐시해도 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;해시 없는 JS/CSS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: no-cache&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;같은 URL의 내용이 바뀔 수 있으므로 재검증이 필요합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공개 이미지&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: public, max-age=86400&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;이미지는 비교적 변경 빈도가 낮고 캐시 효과가 큽니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공개 API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: public, max-age=60, stale-while-revalidate=300&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;짧게 캐시하고 갱신 지연을 숨길 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용자별 API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: private, no-cache&lt;/code&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;code&gt;Cache-Control: no-store&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;저장 자체를 피해야 합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN 캐시 우선&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: no-cache, s-maxage=600&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;브라우저와 CDN의 캐시 시간을 분리할 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;장애 시 이전 데이터 허용&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: max-age=60, stale-if-error=86400&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;서버 오류가 나도 이전 응답을 보여줄 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;faq&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자주 묻는 질문&lt;/h2&gt;
&lt;div class=&quot;webcache_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q1. no-cache와 no-store는 같은 의미인가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아닙니다. &lt;code&gt;no-cache&lt;/code&gt;는 캐시에 저장될 수 있지만 재사용하기 전에 서버에 확인하라는 의미입니다. 반면 &lt;code&gt;no-store&lt;/code&gt;는 응답을 캐시에 저장하지 말라는 의미입니다. 개인정보, 인증, 결제 관련 응답에는 &lt;code&gt;no-store&lt;/code&gt;가 더 적합합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;webcache_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q2. CSS와 JavaScript가 배포 후에도 예전 파일로 보이는 이유는 무엇인가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 브라우저 캐시, CDN 캐시, 서비스 워커 캐시 중 하나가 오래된 파일을 반환하고 있기 때문입니다. 가장 안정적인 해결책은 빌드할 때 파일명에 해시를 붙이고, HTML은 &lt;code&gt;no-cache&lt;/code&gt;, 해시가 붙은 정적 파일은 긴 캐시를 적용하는 방식입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;webcache_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q3. 정적 파일은 무조건 오래 캐시해도 되나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명에 해시가 붙어 있고, 내용이 바뀌면 URL도 바뀌는 구조라면 오래 캐시해도 괜찮습니다. 하지만 &lt;code&gt;/app.js&lt;/code&gt;, &lt;code&gt;/style.css&lt;/code&gt;처럼 같은 URL의 내용을 계속 덮어쓰는 구조라면 긴 캐시는 위험합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;webcache_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q4. CDN 캐시와 브라우저 캐시는 어떻게 다르게 봐야 하나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저 캐시는 사용자 기기에 저장되는 캐시이고, CDN 캐시는 서버와 사용자 사이의 엣지 서버에 저장되는 캐시입니다. CDN 캐시는 여러 사용자에게 공유될 수 있으므로 사용자별 응답이나 개인정보 응답은 절대 공유 캐시에 저장되지 않도록 해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;webcache_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q5. 웹페이지 캐시 문제를 가장 빠르게 확인하는 방법은 무엇인가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Chrome DevTools의 Network 탭에서 &lt;code&gt;Cache-Control&lt;/code&gt;, &lt;code&gt;ETag&lt;/code&gt;, &lt;code&gt;Last-Modified&lt;/code&gt;, &lt;code&gt;Age&lt;/code&gt;, &lt;code&gt;CF-Cache-Status&lt;/code&gt;, 상태 코드 &lt;code&gt;200&lt;/code&gt;/&lt;code&gt;304&lt;/code&gt;를 확인하는 것이 좋습니다. 브라우저 캐시가 아니라 CDN이나 서비스 워커가 원인일 수도 있으므로 한 계층씩 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;conclusion&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;좋은 캐시 전략은 &amp;ldquo;무조건 캐시&amp;rdquo;도 &amp;ldquo;무조건 금지&amp;rdquo;도 아니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시는 웹 성능 최적화에서 가장 기본적이면서도 가장 실수하기 쉬운 영역입니다. 초보 개발자는 캐시 때문에 화면이 안 바뀌면 &amp;ldquo;캐시를 다 꺼야겠다&amp;rdquo;고 생각하기 쉽습니다. 하지만 실무에서는 반대로 접근해야 합니다.&lt;/p&gt;
&lt;div class=&quot;webcache_good&quot;&gt;
&lt;ul class=&quot;webcache_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바뀌지 않는 파일은 강하게 캐시합니다.&lt;/li&gt;
&lt;li&gt;바뀔 수 있는 HTML은 매번 재검증합니다.&lt;/li&gt;
&lt;li&gt;개인정보는 공유 캐시에 절대 넣지 않습니다.&lt;/li&gt;
&lt;li&gt;CDN 캐시와 브라우저 캐시를 분리해서 봅니다.&lt;/li&gt;
&lt;li&gt;파일명 해시, ETag, Last-Modified, Cache-Control을 함께 설계합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시를 잘 다루면 사이트는 훨씬 빨라지고 서버 비용은 줄어듭니다. 반대로 캐시를 잘못 다루면 일부 사용자만 오래된 파일을 보고, 일부 사용자만 오류가 나며, 배포 후 원인 추적이 어려워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 좋은 캐시 전략은 &amp;ldquo;빠르게 보여줄 것&amp;rdquo;과 &amp;ldquo;정확하게 보여줄 것&amp;rdquo;을 구분하는 일입니다. 정적 리소스는 믿고 오래 보관하고, HTML과 민감 데이터는 조심스럽게 확인하고, CDN은 별도의 계층으로 관리해야 합니다. 이 원칙만 지켜도 대부분의 웹 캐시 문제는 훨씬 쉽게 해결할 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;refs&quot; class=&quot;webcache_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료 : 공식문서&lt;/h2&gt;
&lt;div class=&quot;webcache_box&quot;&gt;
&lt;ol class=&quot;webcache_refs&quot; style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ietf.org/rfc/rfc9111.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; RFC 9111 : HTTP Caching &lt;/a&gt; &lt;br /&gt;HTTP 캐시 동작, 저장 조건, 재검증, Cache-Control 지시어의 표준 기준을 확인할 수 있는 문서입니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Reference/Headers/Cache-Control&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; MDN : Cache-Control header &lt;/a&gt; &lt;br /&gt;&lt;code&gt;max-age&lt;/code&gt;, &lt;code&gt;s-maxage&lt;/code&gt;, &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;private&lt;/code&gt;, &lt;code&gt;no-cache&lt;/code&gt;, &lt;code&gt;no-store&lt;/code&gt;, &lt;code&gt;immutable&lt;/code&gt;, &lt;code&gt;stale-while-revalidate&lt;/code&gt; 같은 옵션을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; MDN : HTTP caching &lt;/a&gt; &lt;br /&gt;브라우저 캐시, 공유 캐시, fresh/stale, 재검증 흐름을 전체적으로 이해하는 데 좋은 문서입니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; MDN : ETag header &lt;/a&gt; &lt;br /&gt;리소스 버전 식별자와 조건부 요청, &lt;code&gt;304 Not Modified&lt;/code&gt; 흐름을 이해할 때 참고하기 좋습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Vary&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; MDN : Vary header &lt;/a&gt; &lt;br /&gt;요청 헤더에 따라 응답이 달라지는 경우 캐시 키를 어떻게 분리해야 하는지 설명합니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Request/cache&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; MDN : Request.cache &lt;/a&gt; &lt;br /&gt;&lt;code&gt;fetch&lt;/code&gt; 요청에서 사용할 수 있는 &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;no-store&lt;/code&gt;, &lt;code&gt;reload&lt;/code&gt;, &lt;code&gt;no-cache&lt;/code&gt;, &lt;code&gt;force-cache&lt;/code&gt;, &lt;code&gt;only-if-cached&lt;/code&gt; 옵션을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/articles/stale-while-revalidate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; web.dev : Keeping things fresh with stale-while-revalidate &lt;/a&gt; &lt;br /&gt;&lt;code&gt;stale-while-revalidate&lt;/code&gt;가 어떻게 즉시성과 최신성 사이의 균형을 잡는지 설명하는 Google web.dev 문서입니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Chrome DevTools : Network features reference &lt;/a&gt; &lt;br /&gt;Network 탭에서 캐시 비활성화, 브라우저 캐시 삭제, 네트워크 요청 분석을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nginx.org/en/docs/http/ngx_http_headers_module.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Nginx : ngx_http_headers_module &lt;/a&gt; &lt;br /&gt;Nginx에서 &lt;code&gt;add_header&lt;/code&gt;, &lt;code&gt;expires&lt;/code&gt;로 &lt;code&gt;Expires&lt;/code&gt;와 &lt;code&gt;Cache-Control&lt;/code&gt; 헤더를 제어하는 방법을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://httpd.apache.org/docs/current/en/mod/mod_expires.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Apache : mod_expires &lt;/a&gt; &lt;br /&gt;Apache에서 &lt;code&gt;Expires&lt;/code&gt;와 &lt;code&gt;Cache-Control: max-age&lt;/code&gt;를 생성하는 방법을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://httpd.apache.org/docs/current/en/mod/mod_headers.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Apache : mod_headers &lt;/a&gt; &lt;br /&gt;Apache에서 응답 헤더를 추가, 변경, 제거하는 &lt;code&gt;Header&lt;/code&gt; 지시어를 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/search/docs/fundamentals/seo-starter-guide&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Google Search Central : SEO Starter Guide &lt;/a&gt; &lt;br /&gt;검색엔진이 콘텐츠를 이해하기 쉽게 만드는 기본적인 SEO 원칙을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/search/docs/appearance/title-link&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Google Search Central : Influencing title links &lt;/a&gt; &lt;br /&gt;검색 결과에 표시되는 제목 링크를 더 명확하게 만드는 방법을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/search/docs/appearance/snippet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Google Search Central : Control your snippets in search results &lt;/a&gt; &lt;br /&gt;검색 결과 설명문, 즉 메타 디스크립션 작성 기준을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/search/docs/fundamentals/creating-helpful-content&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; Google Search Central : Creating helpful, reliable, people-first content &lt;/a&gt; &lt;br /&gt;검색엔진만을 위한 글이 아니라 독자에게 실제로 도움이 되는 콘텐츠를 만드는 기준을 확인할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;webcache_section&quot;&gt;&lt;/section&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
    {
      &quot;@context&quot;: &quot;https://schema.org&quot;,
      &quot;@type&quot;: &quot;Article&quot;,
      &quot;headline&quot;: &quot;웹페이지 캐시 완전 정리 : Cache-Control부터 브라우저 캐시, CDN 캐시까지&quot;,
      &quot;description&quot;: &quot;웹페이지 캐시의 원리부터 Cache-Control, no-cache와 no-store 차이, ETag, CDN 캐시, Nginx 설정, fetch 캐시 옵션까지 실무 중심으로 정리한 웹 성능 최적화 가이드입니다.&quot;,
      &quot;author&quot;: {
        &quot;@type&quot;: &quot;Person&quot;,
        &quot;name&quot;: &quot;OdinBOX&quot;
      },
      &quot;publisher&quot;: {
        &quot;@type&quot;: &quot;Organization&quot;,
        &quot;name&quot;: &quot;OdinBOX&quot;
      },
      &quot;mainEntityOfPage&quot;: {
        &quot;@type&quot;: &quot;WebPage&quot;,
        &quot;@id&quot;: &quot;https://odinbox.co.kr/&quot;
      },
      &quot;keywords&quot;: [
        &quot;웹페이지 캐시&quot;,
        &quot;Cache-Control&quot;,
        &quot;브라우저 캐시&quot;,
        &quot;CDN 캐시&quot;,
        &quot;no-cache&quot;,
        &quot;no-store&quot;,
        &quot;ETag&quot;,
        &quot;Nginx 캐시&quot;,
        &quot;웹 성능 최적화&quot;
      ]
    }
    &lt;/script&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
    {
      &quot;@context&quot;: &quot;https://schema.org&quot;,
      &quot;@type&quot;: &quot;BreadcrumbList&quot;,
      &quot;itemListElement&quot;: [
        {
          &quot;@type&quot;: &quot;ListItem&quot;,
          &quot;position&quot;: 1,
          &quot;name&quot;: &quot;Home&quot;,
          &quot;item&quot;: &quot;https://odinbox.co.kr/&quot;
        },
        {
          &quot;@type&quot;: &quot;ListItem&quot;,
          &quot;position&quot;: 2,
          &quot;name&quot;: &quot;Web Development&quot;,
          &quot;item&quot;: &quot;https://odinbox.co.kr/category/Web%20Development&quot;
        },
        {
          &quot;@type&quot;: &quot;ListItem&quot;,
          &quot;position&quot;: 3,
          &quot;name&quot;: &quot;웹페이지 캐시 완전 정리&quot;,
          &quot;item&quot;: &quot;https://odinbox.co.kr/&quot;
        }
      ]
    }
    &lt;/script&gt;
&lt;/article&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>Cache-Control사용법</category>
      <category>CDN 캐시 제어 방법</category>
      <category>ETag 304 Not Modified</category>
      <category>Nginx Cache-Control 설정</category>
      <category>no-cache no-store 차이</category>
      <category>stale-while-revalidate 설명</category>
      <category>브라우저 캐시 삭제 원리</category>
      <category>웹 성능 최적화 캐시 전략</category>
      <category>웹페이지캐시설정방법</category>
      <category>정적 파일 캐시 설정</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/586</guid>
      <comments>https://odinbox.tistory.com/586#entry586comment</comments>
      <pubDate>Sat, 23 May 2026 15:55:02 +0900</pubDate>
    </item>
    <item>
      <title>AI 코딩 에이전트 시대! 개발자는 사라질까, 아니면 더 강해질까?</title>
      <link>https://odinbox.tistory.com/585</link>
      <description>&lt;div id=&quot;odin_reactdoc_ai_post&quot; class=&quot;odin_reactdoc_ai_post&quot;&gt;
&lt;style&gt;
  #odin_reactdoc_ai_post {
    color-scheme: light;
    --doc-bg: #ffffff;
    --doc-page-bg: #f7f9fc;
    --doc-text: #1f2937;
    --doc-title: #111827;
    --doc-muted: #5f6b7a;
    --doc-subtle: #6b7280;
    --doc-border: #e5e7eb;
    --doc-border-strong: #d1d5db;
    --doc-blue: #087ea4;
    --doc-blue-dark: #05617d;
    --doc-blue-soft: #e6f7fb;
    --doc-yellow-soft: #fff8e6;
    --doc-green-soft: #ecfdf5;
    --doc-red-soft: #fef2f2;
    --doc-code-bg: #f3f4f6;
    --doc-code-text: #111827;
    --doc-shadow: 0 10px 30px rgba(15, 23, 42, 0.06);

    max-width: 1160px;
    margin: 0 auto;
    padding: 28px 16px 70px;
    background: var(--doc-page-bg);
    color: var(--doc-text);
    font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans KR&quot;, &quot;Apple SD Gothic Neo&quot;, Arial, sans-serif;
    line-height: 1.82;
    letter-spacing: -0.025em;
    word-break: keep-all;
    box-sizing: border-box;
  }

  #odin_reactdoc_ai_post * {
    box-sizing: border-box;
  }

  #odin_reactdoc_ai_post a {
    color: var(--doc-blue);
    font-weight: 700;
    text-decoration: none;
    border-bottom: 1px solid rgba(8, 126, 164, 0.28);
  }

  #odin_reactdoc_ai_post a:hover {
    color: var(--doc-blue-dark);
    border-bottom-color: var(--doc-blue-dark);
  }

  #odin_reactdoc_ai_post p {
    margin: 14px 0;
    color: var(--doc-text);
    font-size: 16.5px;
  }

  #odin_reactdoc_ai_post strong {
    color: var(--doc-title);
    font-weight: 800;
  }

  #odin_reactdoc_ai_post ul,
  #odin_reactdoc_ai_post ol {
    margin: 12px 0 0;
    padding-left: 22px;
  }

  #odin_reactdoc_ai_post li {
    margin: 7px 0;
    color: var(--doc-text);
  }

  #odin_reactdoc_ai_post .reactdoc_image_area {
    margin: 0 auto 22px;
    padding: 22px;
    border: 1px solid var(--doc-border);
    border-radius: 18px;
    background: #ffffff;
    text-align: center;
    box-shadow: var(--doc-shadow);
  }

  #odin_reactdoc_ai_post .reactdoc_image_area p {
    margin: 0;
  }

  #odin_reactdoc_ai_post .reactdoc_image_area img {
    max-width: 400px !important;
    width: 100% !important;
    height: auto !important;
    border-radius: 16px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.10);
  }

  #odin_reactdoc_ai_post .reactdoc_page {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 28px;
    align-items: start;
  }

  #odin_reactdoc_ai_post .reactdoc_sidebar {
    position: sticky;
    top: 18px;
    padding: 22px 18px;
    border: 1px solid var(--doc-border);
    border-radius: 18px;
    background: #ffffff;
    box-shadow: var(--doc-shadow);
  }

  #odin_reactdoc_ai_post .reactdoc_sidebar_title {
    margin: 0 0 14px;
    color: var(--doc-title);
    font-size: 15px;
    font-weight: 850;
  }

  #odin_reactdoc_ai_post .reactdoc_nav {
    display: grid;
    gap: 5px;
  }

  #odin_reactdoc_ai_post .reactdoc_nav a {
    display: block;
    padding: 8px 10px;
    border: 0;
    border-radius: 10px;
    color: #4b5563;
    font-size: 14px;
    font-weight: 650;
  }

  #odin_reactdoc_ai_post .reactdoc_nav a:hover {
    background: var(--doc-blue-soft);
    color: var(--doc-blue-dark);
  }

  #odin_reactdoc_ai_post .reactdoc_content {
    min-width: 0;
    padding: 38px 42px;
    border: 1px solid var(--doc-border);
    border-radius: 20px;
    background: #ffffff;
    box-shadow: var(--doc-shadow);
  }

  #odin_reactdoc_ai_post .reactdoc_header {
    padding-bottom: 28px;
    border-bottom: 1px solid var(--doc-border);
  }

  #odin_reactdoc_ai_post .reactdoc_kicker {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
    padding: 7px 12px;
    border-radius: 999px;
    background: var(--doc-blue-soft);
    color: var(--doc-blue-dark);
    font-size: 13px;
    font-weight: 800;
  }

  #odin_reactdoc_ai_post .reactdoc_kicker::before {
    content: &quot;&quot;;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--doc-blue);
  }

  #odin_reactdoc_ai_post h1 {
    margin: 0;
    color: var(--doc-title);
    font-size: clamp(32px, 5vw, 48px);
    line-height: 1.18;
    letter-spacing: -0.055em;
    font-weight: 900;
  }

  #odin_reactdoc_ai_post .reactdoc_description {
    max-width: 780px;
    margin-top: 18px;
    color: var(--doc-muted);
    font-size: 18px;
    line-height: 1.78;
  }

  #odin_reactdoc_ai_post .reactdoc_meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 22px;
  }

  #odin_reactdoc_ai_post .reactdoc_meta span {
    display: inline-flex;
    padding: 7px 10px;
    border: 1px solid var(--doc-border);
    border-radius: 999px;
    background: #ffffff;
    color: #4b5563;
    font-size: 13px;
    font-weight: 700;
  }

  #odin_reactdoc_ai_post .reactdoc_notice {
    margin: 26px 0 0;
    padding: 16px 18px;
    border-left: 4px solid var(--doc-blue);
    border-radius: 12px;
    background: var(--doc-blue-soft);
    color: #164e63;
  }

  #odin_reactdoc_ai_post .reactdoc_notice p {
    margin: 0;
    color: #164e63;
    font-size: 15.5px;
  }

  #odin_reactdoc_ai_post .reactdoc_section {
    padding: 34px 0;
    border-bottom: 1px solid var(--doc-border);
  }

  #odin_reactdoc_ai_post .reactdoc_section:last-child {
    border-bottom: 0;
    padding-bottom: 0;
  }

  #odin_reactdoc_ai_post h2 {
    margin: 0 0 18px;
    color: var(--doc-title);
    font-size: 28px;
    line-height: 1.35;
    letter-spacing: -0.045em;
    font-weight: 900;
  }

  #odin_reactdoc_ai_post h3 {
    margin: 26px 0 12px;
    color: var(--doc-title);
    font-size: 21px;
    line-height: 1.45;
    letter-spacing: -0.035em;
    font-weight: 850;
  }

  #odin_reactdoc_ai_post .reactdoc_lead {
    padding: 20px 22px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
    background: #fbfdff;
    color: var(--doc-text);
    font-size: 17px;
    font-weight: 650;
  }

  #odin_reactdoc_ai_post .reactdoc_toc_inline {
    margin-top: 20px;
    padding: 20px 22px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
    background: #ffffff;
  }

  #odin_reactdoc_ai_post .reactdoc_toc_inline strong {
    display: block;
    margin-bottom: 8px;
  }

  #odin_reactdoc_ai_post .reactdoc_card_grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
    margin-top: 18px;
  }

  #odin_reactdoc_ai_post .reactdoc_card {
    padding: 18px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
    background: #ffffff;
  }

  #odin_reactdoc_ai_post .reactdoc_card b {
    display: block;
    margin-bottom: 7px;
    color: var(--doc-title);
    font-size: 16px;
  }

  #odin_reactdoc_ai_post .reactdoc_card span {
    display: block;
    color: var(--doc-muted);
    font-size: 14.5px;
    line-height: 1.7;
  }

  #odin_reactdoc_ai_post .reactdoc_table_wrap {
    overflow-x: auto;
    margin-top: 18px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
  }

  #odin_reactdoc_ai_post table {
    width: 100%;
    min-width: 760px;
    border-collapse: collapse;
    background: #ffffff;
  }

  #odin_reactdoc_ai_post th,
  #odin_reactdoc_ai_post td {
    padding: 15px 16px;
    border-bottom: 1px solid var(--doc-border);
    text-align: left;
    vertical-align: top;
    font-size: 14.8px;
  }

  #odin_reactdoc_ai_post th {
    background: #f9fafb;
    color: var(--doc-title);
    font-weight: 850;
  }

  #odin_reactdoc_ai_post td {
    color: var(--doc-text);
  }

  #odin_reactdoc_ai_post tr:last-child td {
    border-bottom: 0;
  }

  #odin_reactdoc_ai_post .reactdoc_callout {
    margin-top: 22px;
    padding: 18px 20px;
    border-radius: 14px;
    border: 1px solid var(--doc-border);
  }

  #odin_reactdoc_ai_post .reactdoc_callout.info {
    background: var(--doc-blue-soft);
    border-color: #bae6fd;
  }

  #odin_reactdoc_ai_post .reactdoc_callout.warning {
    background: var(--doc-yellow-soft);
    border-color: #fde68a;
  }

  #odin_reactdoc_ai_post .reactdoc_callout.success {
    background: var(--doc-green-soft);
    border-color: #bbf7d0;
  }

  #odin_reactdoc_ai_post .reactdoc_callout.danger {
    background: var(--doc-red-soft);
    border-color: #fecaca;
  }

  #odin_reactdoc_ai_post .reactdoc_callout p {
    margin: 0;
    color: var(--doc-text);
  }

  #odin_reactdoc_ai_post .reactdoc_split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-top: 18px;
  }

  #odin_reactdoc_ai_post .reactdoc_panel {
    padding: 20px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
    background: #ffffff;
  }

  #odin_reactdoc_ai_post .reactdoc_panel.good {
    border-top: 4px solid #10b981;
  }

  #odin_reactdoc_ai_post .reactdoc_panel.bad {
    border-top: 4px solid #ef4444;
  }

  #odin_reactdoc_ai_post .reactdoc_panel h3 {
    margin-top: 0;
    font-size: 19px;
  }

  #odin_reactdoc_ai_post .reactdoc_steps {
    display: grid;
    gap: 12px;
    margin-top: 18px;
    counter-reset: step;
  }

  #odin_reactdoc_ai_post .reactdoc_step {
    position: relative;
    padding: 18px 20px 18px 58px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
    background: #ffffff;
  }

  #odin_reactdoc_ai_post .reactdoc_step::before {
    counter-increment: step;
    content: counter(step);
    position: absolute;
    top: 18px;
    left: 18px;
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: var(--doc-blue);
    color: #ffffff;
    font-size: 13px;
    font-weight: 900;
  }

  #odin_reactdoc_ai_post .reactdoc_step b {
    display: block;
    margin-bottom: 5px;
    color: var(--doc-title);
    font-size: 16.5px;
  }

  #odin_reactdoc_ai_post .reactdoc_step span {
    display: block;
    color: var(--doc-muted);
    font-size: 14.8px;
    line-height: 1.72;
  }

  #odin_reactdoc_ai_post .reactdoc_ref_list {
    display: grid;
    gap: 12px;
    margin-top: 18px;
  }

  #odin_reactdoc_ai_post .reactdoc_ref {
    padding: 18px 20px;
    border: 1px solid var(--doc-border);
    border-radius: 16px;
    background: #ffffff;
  }

  #odin_reactdoc_ai_post .reactdoc_ref b {
    display: block;
    margin-bottom: 6px;
  }

  #odin_reactdoc_ai_post .reactdoc_ref span {
    display: block;
    margin-top: 7px;
    color: var(--doc-muted);
    font-size: 14.2px;
    line-height: 1.68;
  }

  #odin_reactdoc_ai_post .reactdoc_codebox {
    margin-top: 14px;
    padding: 16px 18px;
    border: 1px solid var(--doc-border);
    border-radius: 14px;
    background: var(--doc-code-bg);
    color: var(--doc-code-text);
    font-family: Consolas, Monaco, &quot;Courier New&quot;, monospace;
    font-size: 14px;
    line-height: 1.7;
    white-space: normal;
  }

  #odin_reactdoc_ai_post .reactdoc_tag_list {
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
    margin-top: 16px;
  }

  #odin_reactdoc_ai_post .reactdoc_tag_list span {
    display: inline-flex;
    padding: 7px 12px;
    border-radius: 999px;
    background: var(--doc-blue-soft);
    color: #075985;
    font-size: 13.5px;
    font-weight: 800;
  }

  @media (max-width: 900px) {
    #odin_reactdoc_ai_post .reactdoc_page {
      grid-template-columns: 1fr;
    }

    #odin_reactdoc_ai_post .reactdoc_sidebar {
      position: relative;
      top: auto;
    }

    #odin_reactdoc_ai_post .reactdoc_nav {
      grid-template-columns: repeat(2, 1fr);
    }

    #odin_reactdoc_ai_post .reactdoc_content {
      padding: 30px 24px;
    }

    #odin_reactdoc_ai_post .reactdoc_card_grid,
    #odin_reactdoc_ai_post .reactdoc_split {
      grid-template-columns: 1fr;
    }
  }

  @media (max-width: 640px) {
    #odin_reactdoc_ai_post {
      padding: 18px 10px 50px;
      word-break: normal;
    }

    #odin_reactdoc_ai_post .reactdoc_content {
      padding: 26px 18px;
      border-radius: 16px;
    }

    #odin_reactdoc_ai_post .reactdoc_nav {
      grid-template-columns: 1fr;
    }

    #odin_reactdoc_ai_post h1 {
      font-size: 31px;
    }

    #odin_reactdoc_ai_post h2 {
      font-size: 24px;
    }

    #odin_reactdoc_ai_post .reactdoc_description {
      font-size: 16px;
    }
  }
&lt;/style&gt;
&lt;div class=&quot;reactdoc_image_area&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HXMes/dJMcahdnQIO/VuH4UsqdFtkB3sK5DeQH50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HXMes/dJMcahdnQIO/VuH4UsqdFtkB3sK5DeQH50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HXMes/dJMcahdnQIO/VuH4UsqdFtkB3sK5DeQH50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHXMes%2FdJMcahdnQIO%2FVuH4UsqdFtkB3sK5DeQH50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;reactdoc_page&quot;&gt;
&lt;aside class=&quot;reactdoc_sidebar&quot;&gt;
&lt;div class=&quot;reactdoc_sidebar_title&quot;&gt;문서 목차&lt;/div&gt;
&lt;nav class=&quot;reactdoc_nav&quot;&gt;&lt;a href=&quot;#ai-doc-overview&quot;&gt;개요&lt;/a&gt; &lt;a href=&quot;#ai-doc-summary&quot;&gt;핵심 요약&lt;/a&gt; &lt;a href=&quot;#ai-doc-definition&quot;&gt;용어 정의&lt;/a&gt; &lt;a href=&quot;#ai-doc-tools&quot;&gt;주요 도구&lt;/a&gt; &lt;a href=&quot;#ai-doc-facts&quot;&gt;자료 기반 사실&lt;/a&gt; &lt;a href=&quot;#ai-doc-role&quot;&gt;개발자 역할 변화&lt;/a&gt; &lt;a href=&quot;#ai-doc-junior&quot;&gt;초보 개발자 관점&lt;/a&gt; &lt;a href=&quot;#ai-doc-company&quot;&gt;기업 관점&lt;/a&gt; &lt;a href=&quot;#ai-doc-opinion&quot;&gt;나의 생각&lt;/a&gt; &lt;a href=&quot;#ai-doc-reference&quot;&gt;참고 문서&lt;/a&gt; &lt;a href=&quot;#ai-doc-seo&quot;&gt;SEO 정보&lt;/a&gt;&lt;/nav&gt;&lt;/aside&gt;
&lt;main class=&quot;reactdoc_content&quot;&gt;&lt;header class=&quot;reactdoc_header&quot;&gt;
&lt;p class=&quot;reactdoc_description&quot; data-ke-size=&quot;size16&quot;&gt;AI 코딩 도구는 이제 단순 자동완성 도구를 넘어, 코드베이스를 이해하고 파일을 수정하며 테스트와 Pull Request 흐름까지 지원하는 방향으로 발전하고 있습니다. 이 글은 AI 코딩 에이전트가 개발자의 역할을 어떻게 바꾸고 있는지 공식 자료와 현실적인 관점으로 정리한 문서입니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_meta&quot;&gt;&lt;span&gt;주제 : AI 코딩 에이전트&lt;/span&gt; &lt;span&gt;형식 : 기술 브리핑&lt;/span&gt; &lt;span&gt;대상 : 개발자 / 비전공자&lt;/span&gt; &lt;span&gt;기준 : 2026년 5월&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_notice&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 개인적인 생각만으로 작성한 글이 아니라 Stack Overflow 개발자 설문, OpenAI Codex, GitHub Copilot cloud agent, Anthropic Claude Code 공식 자료를 함께 참고해 정리했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;section id=&quot;ai-doc-overview&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요, AI는 개발자의 작업 흐름 안으로 들어오고 있다&lt;/h2&gt;
&lt;p class=&quot;reactdoc_lead&quot; data-ke-size=&quot;size16&quot;&gt;예전의 AI 코딩 도구는 개발자가 코드를 입력하면 다음 줄을 추천하거나, 간단한 함수를 만들어주는 보조 도구에 가까웠습니다. 하지만 최근의 AI 코딩 에이전트는 코드베이스를 읽고, 파일을 수정하고, 테스트와 리뷰 흐름까지 지원하는 방향으로 발전하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 요즘 개발자 커뮤니티에서 자주 나오는 질문이 있습니다. &lt;b&gt;&amp;ldquo;AI가 이 정도까지 할 수 있다면 개발자는 앞으로 필요 없어지는 것 아닐까?&amp;rdquo;&lt;/b&gt; 이 질문은 충분히 나올 수 있습니다. 실제로 AI는 반복적인 코드 작성, 문서 정리, 테스트 초안 작성, 간단한 버그 수정에서 꽤 좋은 생산성을 보여주고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제 개발 업무는 단순히 코드를 만드는 일에서 끝나지 않습니다. 요구사항을 해석하고, 시스템 구조를 설계하고, 운영 환경에서 문제가 없도록 검증하고, 장애가 발생했을 때 책임 있게 대응하는 과정까지 포함됩니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_callout info&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하면, 개발자는 사라지는 것이 아니라 역할이 바뀌고 있습니다. 단순히 코드를 많이 작성하는 사람보다, 문제를 정확히 정의하고 AI가 만든 결과를 검증할 수 있는 사람이 더 중요해지고 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-summary&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;핵심 요약, 이 글에서 말하는 결론&lt;/h2&gt;
&lt;div class=&quot;reactdoc_card_grid&quot;&gt;
&lt;div class=&quot;reactdoc_card&quot;&gt;&lt;b&gt;AI 도구 사용은 이미 보편화되고 있습니다.&lt;/b&gt; &lt;span&gt; 개발자들은 AI를 실험적으로만 사용하는 것이 아니라 실제 업무 흐름 안에서 사용하고 있습니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_card&quot;&gt;&lt;b&gt;코딩 보조에서 에이전트로 이동 중입니다.&lt;/b&gt; &lt;span&gt; 단순 코드 추천을 넘어 저장소 분석, 구현 계획, 코드 변경, 테스트, PR 흐름까지 지원하는 방향입니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_card&quot;&gt;&lt;b&gt;핵심은 대체가 아니라 검증입니다.&lt;/b&gt; &lt;span&gt; AI가 코드를 만들수록 개발자는 그 코드가 맞는지 판단할 수 있는 기본기와 책임감이 필요합니다. &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;reactdoc_toc_inline&quot;&gt;&lt;b&gt;이 글에서 다루는 주요 질문&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AI 코딩 에이전트는 기존 자동완성 도구와 무엇이 다른가?&lt;/li&gt;
&lt;li&gt;개발자들은 실제로 AI 도구를 얼마나 사용하고 있는가?&lt;/li&gt;
&lt;li&gt;AI가 잘하는 일과 아직 부족한 일은 무엇인가?&lt;/li&gt;
&lt;li&gt;초보 개발자에게 AI는 기회인가, 위기인가?&lt;/li&gt;
&lt;li&gt;기업은 AI 코딩 도구를 어떻게 관리해야 하는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-definition&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;용어 정의, AI 코딩 에이전트란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 코딩 에이전트는 단순히 &amp;ldquo;코드를 생성하는 챗봇&amp;rdquo;이 아닙니다. 개발자가 요청한 작업을 이해하고, 프로젝트의 코드베이스를 분석한 뒤, 필요한 파일을 수정하거나 테스트를 수행하고 변경 결과를 제안하는 개발 보조 도구에 가깝습니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_table_wrap&quot;&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;쉽게 말하면&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;AI 코딩 도구&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;코드 자동완성, 코드 설명, 오류 분석, 문서 작성 등을 지원하는 AI 기반 개발 보조 도구입니다.&lt;/td&gt;
&lt;td&gt;개발자가 물어보면 답변해주는 똑똑한 조수에 가깝습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;AI 코딩 에이전트&lt;/b&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;b&gt;코드베이스&lt;/b&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;b&gt;Pull Request&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;변경한 코드를 프로젝트에 반영하기 전에 리뷰받기 위해 제출하는 변경 요청입니다.&lt;/td&gt;
&lt;td&gt;&amp;ldquo;이 코드 반영해도 될까요?&amp;rdquo;라고 팀에게 검토를 요청하는 과정입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;reactdoc_callout warning&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 코딩 에이전트가 파일을 수정할 수 있다고 해서 결과가 항상 안전하다는 뜻은 아닙니다. 도구가 강력해질수록 코드 리뷰, 테스트, 보안 검토의 중요성도 함께 커집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-tools&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주요 도구, AI 코딩 에이전트는 어디까지 발전했나?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 주요 AI 개발 도구들은 공통적으로 &amp;ldquo;개발자의 질문에 답하는 도구&amp;rdquo;에서 &amp;ldquo;개발 작업의 일부를 수행하는 에이전트&amp;rdquo;로 발전하고 있습니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_table_wrap&quot;&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;개발자 관점에서의 의미&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;OpenAI Codex&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;OpenAI는 Codex를 소프트웨어 개발을 위한 코딩 에이전트로 설명하며, 코드 작성, 리뷰, 디버깅을 돕는다고 안내합니다.&lt;/td&gt;
&lt;td&gt;개발자는 작은 작업 단위를 AI에게 맡기고 결과를 검토하는 방식으로 일할 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;GitHub Copilot cloud agent&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;GitHub 문서에 따르면 Copilot cloud agent는 저장소 조사, 구현 계획 수립, 브랜치 코드 변경, PR 생성 전 단계 작업을 지원합니다.&lt;/td&gt;
&lt;td&gt;GitHub 이슈 기반 작업 처리, 코드 변경 제안, 테스트 보강, 문서 수정이 더 자동화될 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Claude Code&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Anthropic은 Claude Code가 터미널에서 코드베이스 맥락을 탐색하고, 질문에 답하고, 파일 변경을 수행할 수 있다고 설명합니다.&lt;/td&gt;
&lt;td&gt;터미널과 IDE 안에서 자연어 기반으로 코드 분석, 수정, 디버깅을 진행하는 방식이 강화됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은 이 도구들이 단순한 &amp;ldquo;코드 생성기&amp;rdquo;에 머무르지 않는다는 것입니다. 저장소를 이해하고, 변경 계획을 세우고, 직접 수정까지 수행하는 방향으로 발전하고 있습니다. 이 흐름은 앞으로 개발자의 업무 방식을 크게 바꿀 가능성이 높습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-facts&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자료 기반 사실, 개발자들은 AI를 많이 쓰지만 완전히 믿지는 않는다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack Overflow 2025 개발자 설문에 따르면 응답자의 84%가 개발 과정에서 AI 도구를 사용 중이거나 사용할 계획이라고 답했습니다. 또한 전문 개발자의 51%는 매일 AI 도구를 사용한다고 답했습니다. 이 수치만 보면 AI는 이미 개발 현장에 깊게 들어왔다고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 신뢰도는 조금 다르게 나타납니다. 같은 설문에서 AI 도구의 정확도를 신뢰한다는 응답보다 불신한다는 응답이 더 높게 나타났습니다. 즉, 개발자들은 AI를 많이 사용하지만 결과를 그대로 믿지는 않는다는 뜻입니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_split&quot;&gt;
&lt;div class=&quot;reactdoc_panel good&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;긍정적인 변화&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;반복 코드 작성 시간 감소&lt;/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;/div&gt;
&lt;div class=&quot;reactdoc_panel bad&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;현실적인 한계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그럴듯하지만 틀린 코드 생성 가능&lt;/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;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;reactdoc_callout info&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 AI 사용 여부가 아닙니다. 중요한 것은 AI가 만든 결과를 사람이 얼마나 정확하게 검증할 수 있는가입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-role&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개발자의 역할 변화 : 작성자에서 설계자와 검증자로&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 코딩 에이전트가 발전할수록 개발자의 역할은 단순 코드 작성에서 문제 정의, 구조 설계, 결과 검증, 운영 책임 쪽으로 이동합니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_steps&quot;&gt;
&lt;div class=&quot;reactdoc_step&quot;&gt;&lt;b&gt;문제 정의 : 무엇을 만들지 정확히 설명하는 능력&lt;/b&gt; &lt;span&gt; AI에게 좋은 결과를 얻으려면 요구사항, 입력값, 출력값, 예외 조건, 권한, 로그 기준을 명확히 전달해야 합니다. 애매한 요청은 애매한 결과를 만듭니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_step&quot;&gt;&lt;b&gt;구조 설계 : 어디에 어떤 책임을 둘지 판단하는 능력&lt;/b&gt; &lt;span&gt; 서비스 계층, 데이터 접근 계층, 공통 모듈, 예외 처리, 테스트 구조는 프로젝트의 유지보수성을 결정합니다. AI가 파일을 만들 수는 있지만 전체 구조의 책임은 개발자에게 있습니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_step&quot;&gt;&lt;b&gt;결과 검증 : AI가 만든 코드가 맞는지 확인하는 능력&lt;/b&gt; &lt;span&gt; 컴파일 여부, 테스트 통과 여부, 보안 취약점, 성능 문제, DB 정합성, 운영 로그까지 확인해야 실무에 반영할 수 있습니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_step&quot;&gt;&lt;b&gt;운영 책임 : 배포 이후의 문제까지 고려하는 능력&lt;/b&gt; &lt;span&gt; 개발은 코드 작성에서 끝나지 않습니다. 실제 서비스에서는 장애 대응, 사용자 피드백, 데이터 오류, 성능 저하, 보안 이슈까지 함께 고려해야 합니다. &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-junior&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;초보 개발자 관점, AI는 기회이지만 지름길은 아니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초보 개발자에게 AI는 매우 좋은 학습 도구가 될 수 있습니다. 모르는 개념을 설명받을 수 있고, 예제 코드를 빠르게 확인할 수 있으며, 오류 메시지를 해석하는 데 도움을 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 AI를 정답 생성기처럼 사용하면 오히려 위험합니다. 코드를 이해하지 못한 상태에서 붙여넣기만 반복하면, 당장은 빨라 보이지만 문제가 생겼을 때 원인을 찾기 어렵습니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_split&quot;&gt;
&lt;div class=&quot;reactdoc_panel good&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;좋은 사용 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;왜 이런 코드가 나왔는지 질문한다.&lt;/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;/div&gt;
&lt;div class=&quot;reactdoc_panel bad&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;위험한 사용 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드를 이해하지 않고 그대로 붙여넣는다.&lt;/li&gt;
&lt;li&gt;오류가 나면 다시 AI에게만 맡긴다.&lt;/li&gt;
&lt;li&gt;DB, HTTP, 보안, 배포 기본기를 건너뛴다.&lt;/li&gt;
&lt;li&gt;실제 운영 상황을 고려하지 않는다.&lt;/li&gt;
&lt;li&gt;AI 답변을 검증하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;reactdoc_callout success&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 AI는 초보 개발자에게 좋은 기회라고 생각합니다. 다만 &amp;ldquo;나 대신 해주는 도구&amp;rdquo;가 아니라 &amp;ldquo;내가 더 빨리 이해하도록 도와주는 도구&amp;rdquo;로 사용할 때 의미가 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-company&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기업 관점, AI 도입보다 중요한 것은 통제 가능한 사용 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업 입장에서 AI 코딩 도구는 생산성 향상 가능성이 큰 도구입니다. 그러나 회사 코드, 고객 정보, 인증키, 내부 문서가 외부 도구에 입력될 수 있다는 점에서 관리 기준이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 기업은 AI 사용을 무조건 막기보다, 어떤 데이터를 입력할 수 있고, 어떤 작업에 사용할 수 있으며, AI가 만든 코드를 어떤 절차로 검증할지 정해야 합니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_table_wrap&quot;&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;이유&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&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;AI 생성 코드도 일반 코드와 동일하게 리뷰&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;AI가 만든 변경이 기존 기능을 깨뜨릴 수 있기 때문입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;로그와 책임&lt;/td&gt;
&lt;td&gt;AI 사용 내역, 변경 이유, 리뷰자 기록&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;AI 도구는 사용량에 따라 비용이 증가할 수 있기 때문입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;reactdoc_callout warning&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업에서 중요한 것은 &amp;ldquo;AI 사용 여부&amp;rdquo;가 아니라 &amp;ldquo;AI를 안전하게 사용할 수 있는 구조가 있는가&amp;rdquo;입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-opinion&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;나의 생각, AI를 두려워하기보다 다룰 줄 알아야 한다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 AI 코딩 에이전트의 등장은 무섭기도 하고 기대되기도 합니다. 무서운 이유는 분명합니다. 예전보다 훨씬 적은 인원으로 더 많은 일을 처리할 수 있는 시대가 오고 있기 때문입니다. 단순한 작업만 반복하던 방식으로는 경쟁력이 떨어질 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 동시에 기대되는 부분도 있습니다. 개발자는 항상 시간이 부족합니다. 문서도 써야 하고, 버그도 고쳐야 하고, 테스트도 해야 하고, 기존 코드를 분석해야 합니다. 이런 작업 중 일부를 AI가 도와준다면 개발자는 더 중요한 문제에 집중할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 저는 AI를 경쟁자로만 보지는 않습니다. 다만 무조건 믿어서도 안 된다고 생각합니다. AI는 좋은 도구이지만, 좋은 도구일수록 사용하는 사람의 기준이 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 개발자는 AI를 쓰는 사람과 쓰지 않는 사람으로만 나뉘지 않을 것입니다. 더 정확히는 &lt;b&gt;AI를 검증하면서 쓰는 사람&lt;/b&gt;과 &lt;b&gt;AI에게 끌려다니는 사람&lt;/b&gt;으로 나뉠 가능성이 큽니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리, 개발자는 사라지는 것이 아니라 기준이 올라간다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 코딩 에이전트 시대는 이미 시작됐습니다. 이제 개발자는 AI를 쓸지 말지를 고민하는 단계에서 벗어나, 어떻게 안전하고 효율적으로 사용할지 고민해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI는 빠릅니다. 코드도 잘 만들고, 설명도 잘하고, 반복 작업도 잘 처리합니다. 하지만 AI는 최종 책임자가 아닙니다. 서비스 장애가 발생했을 때 책임지는 것은 AI가 아니라 사람입니다. 보안 문제가 생겼을 때도 책임지는 것은 AI가 아니라 조직과 개발자입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 앞으로의 개발자에게 필요한 경쟁력은 명확합니다. 기본기를 갖추고, 시스템을 이해하고, AI에게 일을 잘 맡기고, 그 결과를 냉정하게 검증하는 능력입니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_callout info&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 사라지는 것이 아니라 바뀌고 있습니다. 그리고 이 변화를 잘 받아들이는 개발자는 오히려 더 강해질 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-reference&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 문서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 자료는 이 글을 작성하면서 참고한 공식 문서와 공개 설문 자료입니다. AI 도구의 기능과 정책은 계속 바뀔 수 있으므로 실제 도입 전에는 최신 공식 문서를 다시 확인하는 것이 좋습니다.&lt;/p&gt;
&lt;div class=&quot;reactdoc_ref_list&quot;&gt;
&lt;div class=&quot;reactdoc_ref&quot;&gt;&lt;b&gt;Stack Overflow Developer Survey 2025 : AI Tools in Development&lt;/b&gt; &lt;a href=&quot;https://survey.stackoverflow.co/2025/ai&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://survey.stackoverflow.co/2025/ai&lt;/a&gt; &lt;span&gt;개발자의 AI 도구 사용률, 신뢰도, 개발 프로세스 내 AI 활용 현황을 확인하기 위해 참고했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_ref&quot;&gt;&lt;b&gt;OpenAI Developers : Code Generation / Codex&lt;/b&gt; &lt;a href=&quot;https://developers.openai.com/api/docs/guides/code-generation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developers.openai.com/api/docs/guides/code-generation&lt;/a&gt; &lt;span&gt;OpenAI Codex가 코드 작성, 리뷰, 디버깅을 지원하는 코딩 에이전트로 설명되는 내용을 참고했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_ref&quot;&gt;&lt;b&gt;GitHub Docs : About GitHub Copilot cloud agent&lt;/b&gt; &lt;a href=&quot;https://docs.github.com/en/copilot/concepts/agents/cloud-agent/about-cloud-agent&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.github.com/en/copilot/concepts/agents/cloud-agent/about-cloud-agent&lt;/a&gt; &lt;span&gt;Copilot cloud agent가 저장소 조사, 구현 계획, 코드 변경, PR 흐름을 지원하는 내용을 참고했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;reactdoc_ref&quot;&gt;&lt;b&gt;Anthropic : Claude Code&lt;/b&gt; &lt;a href=&quot;https://claude.com/product/claude-code&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://claude.com/product/claude-code&lt;/a&gt; &lt;span&gt;Claude Code가 터미널, IDE, 웹, Slack에서 코드베이스 이해와 파일 수정을 지원하는 내용을 참고했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ai-doc-seo&quot; class=&quot;reactdoc_section&quot;&gt;
&lt;div class=&quot;reactdoc_codebox&quot;&gt;AI 코딩 에이전트 시대에 개발자는 정말 사라질까? OpenAI Codex, GitHub Copilot cloud agent, Claude Code, Stack Overflow 2025 개발자 설문을 바탕으로 AI가 개발자의 역할을 어떻게 바꾸고 있는지 현실적으로 정리했다.&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;티스토리 태그 10개&lt;/h3&gt;
&lt;div class=&quot;reactdoc_tag_list&quot;&gt;&lt;span&gt;AI코딩&lt;/span&gt; &lt;span&gt;AI코딩에이전트&lt;/span&gt; &lt;span&gt;개발자미래&lt;/span&gt; &lt;span&gt;ChatGPT&lt;/span&gt; &lt;span&gt;ClaudeCode&lt;/span&gt; &lt;span&gt;GitHubCopilot&lt;/span&gt; &lt;span&gt;OpenAICodex&lt;/span&gt; &lt;span&gt;개발트렌드&lt;/span&gt; &lt;span&gt;프로그래밍&lt;/span&gt; &lt;span&gt;IT트렌드&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;/main&gt;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>AI Agent 개발</category>
      <category>ai 개발자 대체</category>
      <category>AI 시대 개발자</category>
      <category>ai 코딩 도구</category>
      <category>chatgpt 코딩</category>
      <category>github 코파일럿 에이전트</category>
      <category>OpenAI Codex</category>
      <category>초보 개발자 AI 활용</category>
      <category>코딩 에이전트</category>
      <category>클로드코드 사용법</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/585</guid>
      <comments>https://odinbox.tistory.com/585#entry585comment</comments>
      <pubDate>Sat, 16 May 2026 17:33:48 +0900</pubDate>
    </item>
    <item>
      <title>나는 지금, 새로운 환경에 배포되는 중입니다</title>
      <link>https://odinbox.tistory.com/584</link>
      <description>&lt;div id=&quot;gwangmyeong_post_wrap&quot; class=&quot;gwangmyeong_post_wrap&quot;&gt;
&lt;style&gt;
    .gwangmyeong_post_wrap {
      max-width: 920px;
      margin: 0 auto;
      padding: 28px 18px;
      font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans KR&quot;, &quot;Apple SD Gothic Neo&quot;, Arial, sans-serif;
      color: #1f2937;
      line-height: 1.85;
      word-break: keep-all;
      letter-spacing: -0.02em;
      background: #ffffff;
    }

    .gwangmyeong_post_wrap * {
      box-sizing: border-box;
    }

    .gwangmyeong_seo_summary {
      margin: 0 0 22px;
      padding: 18px 20px;
      border-radius: 18px;
      background: #f8fafc;
      border: 1px solid #e5e7eb;
      color: #475569;
      font-size: 15px;
      line-height: 1.75;
    }

    .gwangmyeong_hero {
      position: relative;
      overflow: hidden;
      padding: 54px 34px;
      border-radius: 30px;
      background:
        radial-gradient(circle at 18% 18%, rgba(59, 130, 246, 0.30), transparent 34%),
        radial-gradient(circle at 86% 12%, rgba(14, 165, 233, 0.24), transparent 30%),
        radial-gradient(circle at 50% 100%, rgba(125, 211, 252, 0.14), transparent 42%),
        linear-gradient(135deg, #020617 0%, #0f172a 44%, #1e293b 100%);
      color: #ffffff;
      box-shadow: 0 24px 70px rgba(15, 23, 42, 0.28);
      isolation: isolate;
    }

    .gwangmyeong_hero::before {
      content: &quot;&quot;;
      position: absolute;
      top: -120px;
      left: -120px;
      width: 280px;
      height: 280px;
      border-radius: 50%;
      background: rgba(59, 130, 246, 0.22);
      filter: blur(6px);
      animation: gwangmyeong_softFloat 9s ease-in-out infinite alternate;
      z-index: -1;
    }

    .gwangmyeong_hero::after {
      content: &quot;&quot;;
      position: absolute;
      inset: 0;
      background: linear-gradient(120deg, transparent 0%, rgba(255, 255, 255, 0.08) 42%, transparent 64%);
      transform: translateX(-100%);
      animation: gwangmyeong_lightSweep 6s ease-in-out infinite;
      z-index: -1;
    }

    .gwangmyeong_hero_grid {
      display: grid;
      grid-template-columns: 1.25fr 0.75fr;
      gap: 28px;
      align-items: center;
    }

    .gwangmyeong_hero_badge {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      padding: 8px 14px;
      margin-bottom: 20px;
      border: 1px solid rgba(255, 255, 255, 0.26);
      border-radius: 999px;
      background: rgba(255, 255, 255, 0.10);
      color: #dbeafe;
      font-size: 14px;
      font-weight: 800;
      backdrop-filter: blur(10px);
      animation: gwangmyeong_fadeUp 0.75s ease both;
    }

    .gwangmyeong_visual_title {
      margin: 0;
      color: #ffffff;
      font-size: clamp(32px, 5vw, 50px);
      line-height: 1.23;
      letter-spacing: -0.055em;
      font-weight: 950;
      animation: gwangmyeong_fadeUp 0.85s ease both;
      animation-delay: 0.08s;
    }

    .gwangmyeong_visual_title span {
      display: inline;
      color: #93c5fd;
    }

    .gwangmyeong_hero_subtitle {
      margin: 22px 0 0;
      max-width: 720px;
      color: #dbeafe;
      font-size: 17px;
      line-height: 1.9;
      animation: gwangmyeong_fadeUp 0.9s ease both;
      animation-delay: 0.16s;
    }

    .gwangmyeong_thumbnail_card {
      position: relative;
      padding: 12px;
      border-radius: 28px;
      background: rgba(255, 255, 255, 0.12);
      border: 1px solid rgba(255, 255, 255, 0.20);
      box-shadow: 0 20px 44px rgba(0, 0, 0, 0.22);
      backdrop-filter: blur(12px);
      animation: gwangmyeong_floatImage 4.8s ease-in-out infinite;
    }

    .gwangmyeong_thumbnail_card p {
      margin: 0 !important;
    }

    .gwangmyeong_thumbnail_card img {
      display: block;
      width: 100%;
      height: auto;
      border-radius: 22px;
      box-shadow: 0 16px 36px rgba(15, 23, 42, 0.28);
    }

    .gwangmyeong_thumbnail_caption {
      margin-top: 12px;
      color: #dbeafe;
      font-size: 13px;
      line-height: 1.6;
      text-align: center;
      opacity: 0.9;
    }

    .gwangmyeong_meta_box {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 14px;
      margin: 28px 0 0;
      animation: gwangmyeong_fadeUp 0.9s ease both;
      animation-delay: 0.24s;
    }

    .gwangmyeong_meta_item {
      padding: 16px;
      border-radius: 18px;
      background: rgba(255, 255, 255, 0.10);
      border: 1px solid rgba(255, 255, 255, 0.18);
      transition: transform 0.25s ease, background 0.25s ease;
    }

    .gwangmyeong_meta_item:hover {
      transform: translateY(-4px);
      background: rgba(255, 255, 255, 0.15);
    }

    .gwangmyeong_meta_label {
      display: block;
      color: #bfdbfe;
      font-size: 13px;
      font-weight: 800;
      margin-bottom: 4px;
    }

    .gwangmyeong_meta_value {
      display: block;
      color: #ffffff;
      font-size: 16px;
      font-weight: 900;
    }

    .gwangmyeong_section {
      margin-top: 42px;
      padding: 34px;
      border: 1px solid #e5e7eb;
      border-radius: 24px;
      background: #ffffff;
      box-shadow: 0 14px 34px rgba(15, 23, 42, 0.06);
      opacity: 0;
      transform: translateY(22px);
      animation: gwangmyeong_fadeUp 0.85s ease forwards;
    }

    .gwangmyeong_section_title {
      position: relative;
      margin: 0 0 18px;
      padding-left: 16px;
      color: #111827;
      font-size: 26px;
      line-height: 1.35;
      font-weight: 950;
      letter-spacing: -0.04em;
    }

    .gwangmyeong_section_title::before {
      content: &quot;&quot;;
      position: absolute;
      top: 8px;
      left: 0;
      width: 5px;
      height: 26px;
      border-radius: 999px;
      background: linear-gradient(180deg, #2563eb, #38bdf8);
    }

    .gwangmyeong_paragraph {
      margin: 0 0 18px;
      color: #374151;
      font-size: 17px;
    }

    .gwangmyeong_paragraph strong {
      color: #1d4ed8;
      font-weight: 900;
    }

    .gwangmyeong_quote {
      position: relative;
      margin: 28px 0;
      padding: 24px 26px;
      border-left: 6px solid #2563eb;
      border-radius: 18px;
      background: linear-gradient(135deg, #eff6ff 0%, #f8fafc 100%);
      color: #1e3a8a;
      font-size: 18px;
      font-weight: 900;
      line-height: 1.75;
      overflow: hidden;
    }

    .gwangmyeong_quote::after {
      content: &quot;&quot;;
      position: absolute;
      right: -40px;
      bottom: -40px;
      width: 120px;
      height: 120px;
      border-radius: 50%;
      background: rgba(37, 99, 235, 0.08);
    }

    .gwangmyeong_timeline {
      display: grid;
      gap: 16px;
      margin-top: 24px;
    }

    .gwangmyeong_timeline_item {
      display: grid;
      grid-template-columns: 120px 1fr;
      gap: 18px;
      padding: 20px;
      border-radius: 20px;
      background: #f9fafb;
      border: 1px solid #e5e7eb;
      transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
    }

    .gwangmyeong_timeline_item:hover {
      transform: translateY(-4px);
      border-color: #bfdbfe;
      box-shadow: 0 14px 30px rgba(37, 99, 235, 0.10);
    }

    .gwangmyeong_timeline_label {
      color: #2563eb;
      font-weight: 950;
      font-size: 15px;
    }

    .gwangmyeong_timeline_text {
      margin: 0;
      color: #374151;
      font-size: 16px;
    }

    .gwangmyeong_code_card {
      position: relative;
      margin-top: 26px;
      padding: 24px;
      border-radius: 22px;
      background: #0f172a;
      color: #dbeafe;
      box-shadow: 0 18px 42px rgba(15, 23, 42, 0.22);
      overflow-x: auto;
    }

    .gwangmyeong_code_card::before {
      content: &quot;odinbox.dev.log&quot;;
      display: block;
      margin-bottom: 12px;
      color: #93c5fd;
      font-size: 13px;
      font-weight: 900;
      letter-spacing: 0.02em;
    }

    .gwangmyeong_code_card pre {
      margin: 0;
      font-size: 15px;
      line-height: 1.8;
      white-space: pre-wrap;
      font-family: &quot;Consolas&quot;, &quot;Monaco&quot;, &quot;Courier New&quot;, monospace;
    }

    .gwangmyeong_final_box {
      position: relative;
      margin-top: 42px;
      padding: 36px;
      border-radius: 28px;
      background:
        linear-gradient(135deg, rgba(37, 99, 235, 0.10), rgba(56, 189, 248, 0.10)),
        #f8fafc;
      border: 1px solid #dbeafe;
      overflow: hidden;
    }

    .gwangmyeong_final_box::before {
      content: &quot;&quot;;
      position: absolute;
      top: -60px;
      right: -60px;
      width: 180px;
      height: 180px;
      border-radius: 50%;
      background: rgba(37, 99, 235, 0.10);
    }

    .gwangmyeong_final_text {
      position: relative;
      margin: 0;
      color: #1f2937;
      font-size: 19px;
      line-height: 1.9;
      font-weight: 800;
      z-index: 1;
    }

    .gwangmyeong_tag_area {
      margin-top: 34px;
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
    }

    .gwangmyeong_tag {
      display: inline-flex;
      padding: 8px 13px;
      border-radius: 999px;
      background: #eff6ff;
      color: #1d4ed8;
      font-size: 14px;
      font-weight: 900;
      border: 1px solid #bfdbfe;
      transition: transform 0.2s ease, background 0.2s ease;
    }

    .gwangmyeong_tag:hover {
      transform: translateY(-2px);
      background: #dbeafe;
    }

    .gwangmyeong_scroll_button {
      position: fixed;
      right: 20px;
      bottom: 22px;
      z-index: 50;
      width: 46px;
      height: 46px;
      border: none;
      border-radius: 50%;
      background: #2563eb;
      color: #ffffff;
      font-size: 18px;
      font-weight: 900;
      cursor: pointer;
      box-shadow: 0 14px 28px rgba(37, 99, 235, 0.34);
      transition: transform 0.2s ease, opacity 0.2s ease;
      display: none;
    }

    .gwangmyeong_scroll_button:hover {
      transform: translateY(-3px);
      opacity: 0.92;
    }

    @keyframes gwangmyeong_fadeUp {
      from {
        opacity: 0;
        transform: translateY(22px);
      }
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }

    @keyframes gwangmyeong_softFloat {
      from {
        transform: translate(0, 0) scale(1);
      }
      to {
        transform: translate(30px, 26px) scale(1.08);
      }
    }

    @keyframes gwangmyeong_lightSweep {
      0% {
        transform: translateX(-100%);
      }
      45% {
        transform: translateX(100%);
      }
      100% {
        transform: translateX(100%);
      }
    }

    @keyframes gwangmyeong_floatImage {
      0%, 100% {
        transform: translateY(0);
      }
      50% {
        transform: translateY(-8px);
      }
    }

    @media (max-width: 720px) {
      .gwangmyeong_post_wrap {
        padding: 18px 12px;
      }

      .gwangmyeong_hero {
        padding: 36px 20px;
        border-radius: 22px;
      }

      .gwangmyeong_hero_grid {
        grid-template-columns: 1fr;
      }

      .gwangmyeong_thumbnail_card {
        max-width: 320px;
        margin: 4px auto 0;
      }

      .gwangmyeong_meta_box {
        grid-template-columns: 1fr;
      }

      .gwangmyeong_section {
        padding: 24px 20px;
        border-radius: 20px;
      }

      .gwangmyeong_section_title {
        font-size: 23px;
      }

      .gwangmyeong_paragraph {
        font-size: 16px;
      }

      .gwangmyeong_timeline_item {
        grid-template-columns: 1fr;
      }

      .gwangmyeong_scroll_button {
        right: 14px;
        bottom: 16px;
      }
    }

    @media (prefers-reduced-motion: reduce) {
      .gwangmyeong_post_wrap *,
      .gwangmyeong_post_wrap *::before,
      .gwangmyeong_post_wrap *::after {
        animation: none !important;
        transition: none !important;
      }
    }
  &lt;/style&gt;
&lt;article class=&quot;gwangmyeong_article&quot;&gt;
&lt;p class=&quot;gwangmyeong_seo_summary&quot; data-ke-size=&quot;size16&quot;&gt;울산에서 광명으로 올라오며, 최영환이라는 개발자가 오딘박스에 남기는 새로운 시작과 성장의 기록입니다.&lt;/p&gt;
&lt;header class=&quot;gwangmyeong_hero&quot;&gt;
&lt;div class=&quot;gwangmyeong_hero_grid&quot;&gt;
&lt;div class=&quot;gwangmyeong_hero_content&quot;&gt;
&lt;div class=&quot;gwangmyeong_hero_badge&quot;&gt;OdinBOX &amp;middot; Developer Journey &amp;middot; Ulsan to Gwangmyeong&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_visual_title&quot; data-ke-size=&quot;size16&quot;&gt;나는 지금,&lt;br /&gt;&lt;span&gt;새로운 환경에 배포되는 중입니다&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_hero_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;울산에서 쌓아온 시간과 경험을 뒤로하고, 이제는 광명이라는 낯선 도시에서 다시 시작하려 합니다. 개발자 최영환으로서, 그리고 오딘박스라는 이름으로 남기는 이 기록은 설렘과 두려움 사이에서 작성하는 하나의 커밋 메시지 같은 글입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_thumbnail_card&quot; aria-label=&quot;대표 이미지&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F0lc4/dJMcaiDfQzW/R5KXZ32egvPkHCEqkFeG50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F0lc4/dJMcaiDfQzW/R5KXZ32egvPkHCEqkFeG50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F0lc4/dJMcaiDfQzW/R5KXZ32egvPkHCEqkFeG50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF0lc4%2FdJMcaiDfQzW%2FR5KXZ32egvPkHCEqkFeG50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;gwangmyeong_thumbnail_caption&quot;&gt;울산에서 광명으로, 개발자로서 다시 시작하는 기록&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_meta_box&quot;&gt;
&lt;div class=&quot;gwangmyeong_meta_item&quot;&gt;&lt;span class=&quot;gwangmyeong_meta_label&quot;&gt;출발점&lt;/span&gt; &lt;span class=&quot;gwangmyeong_meta_value&quot;&gt;울산&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_meta_item&quot;&gt;&lt;span class=&quot;gwangmyeong_meta_label&quot;&gt;새로운 환경&lt;/span&gt; &lt;span class=&quot;gwangmyeong_meta_value&quot;&gt;광명&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_meta_item&quot;&gt;&lt;span class=&quot;gwangmyeong_meta_label&quot;&gt;기록하는 이름&lt;/span&gt; &lt;span class=&quot;gwangmyeong_meta_value&quot;&gt;최영환 &amp;middot; 오딘박스&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;section class=&quot;gwangmyeong_section&quot;&gt;
&lt;h2 class=&quot;gwangmyeong_section_title&quot; data-ke-size=&quot;size26&quot;&gt;익숙한 울산을 떠난다는 것&lt;/h2&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;오랫동안 울산에서 근무를 하다가, 사무실 위치가 광명으로 이전되면서 저 역시 광명으로 올라오게 되었습니다. 말로는 &amp;ldquo;이전&amp;rdquo;이라는 짧은 단어로 표현할 수 있지만, 제 마음 안에서는 생각보다 많은 감정이 오갔습니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;울산은 저에게 익숙한 도시였습니다. 매일 지나던 길, 익숙한 공기, 일하는 방식, 그리고 제가 개발자로서 조금씩 성장해온 시간이 쌓여 있는 곳이었습니다. 최영환이라는 이름으로 일했고, 오딘박스라는 이름으로 기록하며, 저만의 속도로 하루하루를 쌓아왔습니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이제는 그 익숙함을 잠시 내려놓고, 광명이라는 새로운 환경에서 다시 하루를 시작해야 합니다. 개발자로서 수도권으로 올라오게 되었다는 사실은 솔직히 기쁩니다. 더 많은 기회가 있을 것 같고, 더 넓은 환경에서 성장할 수 있을 것 같고, 지금보다 더 큰 경험을 할 수 있을 것 같다는 기대도 있습니다.&lt;/p&gt;
&lt;div class=&quot;gwangmyeong_quote&quot;&gt;하지만 기대가 크다는 것은, 그만큼 두려움도 함께 따라온다는 뜻이기도 합니다.&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;아직 직접 가보지 않은 길입니다. 어떤 사람들이 기다리고 있을지, 어떤 업무가 펼쳐질지, 내가 그 안에서 잘 적응할 수 있을지 아직은 모릅니다. 그래서 설레면서도 한편으로는 겁이 납니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;gwangmyeong_section&quot;&gt;
&lt;h2 class=&quot;gwangmyeong_section_title&quot; data-ke-size=&quot;size26&quot;&gt;개발자의 이동은 단순한 이사가 아니다&lt;/h2&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;이번 이동은 단순히 근무지가 바뀌는 일이 아닙니다. 저에게는 개발자로서의 환경이 바뀌고, 시야가 바뀌고, 앞으로의 방향이 조금 더 선명해지는 전환점처럼 느껴집니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;개발자는 매일 새로운 문제를 만납니다. 에러 메시지를 보고 원인을 찾고, 복잡한 요구사항을 코드로 풀어내고, 어제는 몰랐던 기술을 오늘은 이해해야 합니다. 어쩌면 광명으로 올라가는 이번 길도 그런 개발 과정과 비슷한 것 같습니다.&lt;/p&gt;
&lt;div class=&quot;gwangmyeong_code_card&quot;&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const gwangmyeong_developer = {
  name: &quot;최영환&quot;,
  brand: &quot;OdinBOX&quot;,
  from: &quot;Ulsan&quot;,
  to: &quot;Gwangmyeong&quot;,
  role: &quot;Developer&quot;,
  feeling: [&quot;설렘&quot;, &quot;두려움&quot;, &quot;기대&quot;, &quot;책임감&quot;],
  commitMessage: &quot;낯선 환경에서도 멈추지 않고 성장하기&quot;
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;처음부터 완벽하게 아는 개발자는 없습니다. 처음부터 모든 길을 알고 출발하는 사람도 없습니다. 중요한 것은 모르는 것을 인정하고, 부딪히고, 기록하고, 다시 고치는 과정이라고 생각합니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;광명이라는 새로운 환경은 저에게 또 다른 운영 서버와도 같습니다. 아직 배포 전이라 어떤 오류가 날지 모르고, 어떤 예외 상황이 생길지 모르지만, 결국 하나씩 로그를 확인하고, 원인을 찾고, 개선해 나가야 합니다.&lt;/p&gt;
&lt;div class=&quot;gwangmyeong_timeline&quot;&gt;
&lt;div class=&quot;gwangmyeong_timeline_item&quot;&gt;
&lt;div class=&quot;gwangmyeong_timeline_label&quot;&gt;울산에서&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_timeline_text&quot; data-ke-size=&quot;size16&quot;&gt;익숙한 환경 속에서 개발자로서의 기본기를 쌓고, 현장의 문제를 마주하며 일하는 법을 배웠습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_timeline_item&quot;&gt;
&lt;div class=&quot;gwangmyeong_timeline_label&quot;&gt;오딘박스에&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_timeline_text&quot; data-ke-size=&quot;size16&quot;&gt;최영환이라는 이름으로 경험을 기록하고, 배운 것을 남기며, 개발자로서의 시간을 정리해왔습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_timeline_item&quot;&gt;
&lt;div class=&quot;gwangmyeong_timeline_label&quot;&gt;광명으로&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_timeline_text&quot; data-ke-size=&quot;size16&quot;&gt;수도권이라는 더 넓은 무대에서 새로운 사람, 새로운 업무, 새로운 가능성을 만나게 되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gwangmyeong_timeline_item&quot;&gt;
&lt;div class=&quot;gwangmyeong_timeline_label&quot;&gt;앞으로&lt;/div&gt;
&lt;p class=&quot;gwangmyeong_timeline_text&quot; data-ke-size=&quot;size16&quot;&gt;두려움이 없어서 가는 것이 아니라, 두려움이 있어도 개발자로서 더 성장하고 싶기 때문에 나아가려 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;gwangmyeong_section&quot;&gt;
&lt;h2 class=&quot;gwangmyeong_section_title&quot; data-ke-size=&quot;size26&quot;&gt;설렘과 두려움 사이에서 남기는 커밋&lt;/h2&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;사실 마음이 마냥 가볍지만은 않습니다. 새로운 곳에서 잘할 수 있을지, 내가 기대만큼 성장할 수 있을지, 때로는 지치고 힘든 순간이 오지는 않을지 걱정도 됩니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;하지만 그런 마음이 든다는 것은, 그만큼 이번 변화가 저에게 중요하다는 의미이기도 합니다. 아무 의미 없는 일이라면 긴장도 하지 않았을 것입니다. 정말 잘하고 싶기 때문에, 더 나아지고 싶기 때문에, 지금 이 길이 조금은 무겁게 느껴지는 것 같습니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;개발자로 일하면서 느낀 것이 있습니다. 어려운 문제일수록 처음에는 막막합니다. 어디서부터 봐야 할지 모르겠고, 해결이 안 될 것 같고, 괜히 내가 부족한 사람처럼 느껴질 때도 있습니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;그런데 로그를 하나씩 보고, 코드를 한 줄씩 따라가고, 원인을 조금씩 좁혀가다 보면 결국 실마리가 보입니다. 인생의 변화도 비슷하지 않을까 생각합니다. 광명에서의 시작도 처음에는 낯설겠지만, 하루하루 쌓다 보면 언젠가는 저만의 흐름을 찾게 될 것입니다.&lt;/p&gt;
&lt;div class=&quot;gwangmyeong_quote&quot;&gt;모르는 길이라서 두렵지만, 모르는 길이기 때문에 성장할 수 있다고 믿습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;gwangmyeong_section&quot;&gt;
&lt;h2 class=&quot;gwangmyeong_section_title&quot; data-ke-size=&quot;size26&quot;&gt;그래도 나는 앞으로 간다&lt;/h2&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;울산에서 광명으로. 이 문장 안에는 단순한 지역 이동 이상의 의미가 담겨 있습니다. 저에게는 익숙함에서 벗어나 새로운 가능성으로 향하는 시작이고, 개발자로서 한 단계 더 넓은 환경에 서게 되는 순간입니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;물론 앞으로 분명히 힘든 날도 있을 것입니다. 지치는 날도 있을 것이고, 생각보다 잘 풀리지 않는 일도 있을 것입니다. 낯선 도시에서 외로움을 느끼는 순간도 있을지 모릅니다.&lt;/p&gt;
&lt;p class=&quot;gwangmyeong_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;그래도 저는 이 길을 한번 걸어가 보려 합니다. 아직 어떤 길인지 모르지만, 모르기 때문에 더 배우고 싶습니다. 아직 완벽하지 않지만, 완벽하지 않기 때문에 더 성장할 수 있다고 믿습니다.&lt;/p&gt;
&lt;div class=&quot;gwangmyeong_final_box&quot;&gt;
&lt;p class=&quot;gwangmyeong_final_text&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;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;div class=&quot;gwangmyeong_tag_area&quot; aria-label=&quot;태그 목록&quot;&gt;&lt;span class=&quot;gwangmyeong_tag&quot;&gt;#최영환&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#오딘박스&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#OdinBOX&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#울산개발자&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#광명개발자&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#개발자일상&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#개발자성장기&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#수도권개발자&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#새로운시작&lt;/span&gt; &lt;span class=&quot;gwangmyeong_tag&quot;&gt;#개발자회고&lt;/span&gt;&lt;/div&gt;
&lt;/article&gt;
&lt;button id=&quot;gwangmyeong_scroll_button&quot; class=&quot;gwangmyeong_scroll_button&quot; type=&quot;button&quot; aria-label=&quot;맨 위로 이동&quot;&gt; &amp;uarr; &lt;/button&gt;
&lt;script&gt;
    function gwangmyeong_scrollToTop() {
      window.scrollTo({
        top: 0,
        behavior: &quot;smooth&quot;
      });
    }

    const gwangmyeong_scrollButton = document.getElementById(&quot;gwangmyeong_scroll_button&quot;);

    if (gwangmyeong_scrollButton) {
      gwangmyeong_scrollButton.addEventListener(&quot;click&quot;, gwangmyeong_scrollToTop);
    }

    window.addEventListener(&quot;scroll&quot;, function gwangmyeong_handleScrollButton() {
      if (!gwangmyeong_scrollButton) {
        return;
      }

      if (window.scrollY &gt; 400) {
        gwangmyeong_scrollButton.style.display = &quot;block&quot;;
      } else {
        gwangmyeong_scrollButton.style.display = &quot;none&quot;;
      }
    });
  &lt;/script&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>개발자블로그</category>
      <category>개발자성장기</category>
      <category>개발자일상</category>
      <category>개발자회고</category>
      <category>광명개발자</category>
      <category>광명생활</category>
      <category>새로운시작</category>
      <category>수도권개발자</category>
      <category>울산에서광명으로</category>
      <category>직장인이야기</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/584</guid>
      <comments>https://odinbox.tistory.com/584#entry584comment</comments>
      <pubDate>Sat, 9 May 2026 23:27:01 +0900</pubDate>
    </item>
    <item>
      <title>Claude AI 프롬프트 잘 쓰는 법, 토큰 절약까지 함께 정리</title>
      <link>https://odinbox.tistory.com/583</link>
      <description>&lt;div&gt;
&lt;style&gt;
  .CLAUDETOK_wrap {
    max-width: 920px !important;
    margin: 0 auto !important;
    padding: 24px 18px 52px !important;
    color: #1f2937 !important;
    font-family: -apple-system, BlinkMacSystemFont, &quot;Noto Sans KR&quot;, &quot;Apple SD Gothic Neo&quot;, &quot;Segoe UI&quot;, sans-serif !important;
    line-height: 1.86 !important;
    word-break: keep-all !important;
    background: #ffffff !important;
  }

  .CLAUDETOK_wrap * {
    box-sizing: border-box !important;
  }

  .CLAUDETOK_hero {
    position: relative !important;
    overflow: hidden !important;
    padding: 48px 34px !important;
    border-radius: 28px !important;
    background:
      radial-gradient(circle at 12% 18%, rgba(96, 165, 250, 0.34), transparent 34%),
      radial-gradient(circle at 90% 10%, rgba(167, 139, 250, 0.28), transparent 32%),
      linear-gradient(135deg, #111827 0%, #1e1b4b 48%, #0f172a 100%) !important;
    color: #ffffff !important;
    box-shadow: 0 26px 62px rgba(15, 23, 42, 0.24) !important;
  }

  .CLAUDETOK_badge {
    display: inline-flex !important;
    align-items: center !important;
    padding: 8px 14px !important;
    border: 1px solid rgba(255,255,255,0.35) !important;
    border-radius: 999px !important;
    background: rgba(255,255,255,0.14) !important;
    color: #ffffff !important;
    font-size: 13px !important;
    font-weight: 800 !important;
    letter-spacing: -0.02em !important;
  }

  .CLAUDETOK_h1 {
    margin: 22px 0 18px !important;
    font-size: clamp(31px, 5vw, 48px) !important;
    line-height: 1.22 !important;
    letter-spacing: -0.055em !important;
    font-weight: 900 !important;
    color: #ffffff !important;
    text-shadow: 0 3px 18px rgba(0, 0, 0, 0.34) !important;
  }

  .CLAUDETOK_hero .CLAUDETOK_h1,
  .CLAUDETOK_hero h1 {
    color: #ffffff !important;
  }

  .CLAUDETOK_lead {
    margin: 0 !important;
    max-width: 780px !important;
    color: #f8fafc !important;
    font-size: 17px !important;
    line-height: 1.9 !important;
    font-weight: 500 !important;
  }

  .CLAUDETOK_hero .CLAUDETOK_lead,
  .CLAUDETOK_hero p {
    color: #f8fafc !important;
  }

  .CLAUDETOK_meta {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    margin-top: 24px !important;
  }

  .CLAUDETOK_meta span {
    padding: 8px 12px !important;
    border-radius: 999px !important;
    background: rgba(255,255,255,0.16) !important;
    color: #ffffff !important;
    font-size: 13px !important;
    font-weight: 700 !important;
  }

  .CLAUDETOK_thumbnail {
    margin: 30px auto 26px !important;
    padding: 20px !important;
    border: 1px solid #e5e7eb !important;
    border-radius: 26px !important;
    background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%) !important;
    box-shadow: 0 16px 38px rgba(15, 23, 42, 0.08) !important;
    text-align: center !important;
  }

  .CLAUDETOK_thumbnail p {
    margin: 0 !important;
  }

  .CLAUDETOK_thumbnail img {
    max-width: 100% !important;
    height: auto !important;
    border-radius: 22px !important;
    box-shadow: 0 18px 40px rgba(15, 23, 42, 0.14) !important;
  }

  .CLAUDETOK_thumbnail_caption {
    margin-top: 14px !important;
    color: #475569 !important;
    font-size: 14px !important;
    font-weight: 800 !important;
  }

  .CLAUDETOK_box {
    margin: 30px 0 !important;
    padding: 25px !important;
    border: 1px solid #e5e7eb !important;
    border-radius: 24px !important;
    background: #ffffff !important;
    box-shadow: 0 14px 34px rgba(15, 23, 42, 0.06) !important;
  }

  .CLAUDETOK_box_blue {
    border-color: #bfdbfe !important;
    background: linear-gradient(180deg, #eff6ff 0%, #ffffff 100%) !important;
  }

  .CLAUDETOK_box_yellow {
    border-color: #fde68a !important;
    background: linear-gradient(180deg, #fffbeb 0%, #ffffff 100%) !important;
  }

  .CLAUDETOK_box_dark {
    border-color: #111827 !important;
    background: #0f172a !important;
    color: #f8fafc !important;
  }

  .CLAUDETOK_box_dark p,
  .CLAUDETOK_box_dark h3 {
    color: #f8fafc !important;
  }

  .CLAUDETOK_h2 {
    margin: 50px 0 18px !important;
    padding-left: 14px !important;
    border-left: 6px solid #4f46e5 !important;
    color: #111827 !important;
    font-size: 27px !important;
    line-height: 1.42 !important;
    letter-spacing: -0.04em !important;
    font-weight: 900 !important;
  }

  .CLAUDETOK_h3 {
    margin: 30px 0 14px !important;
    color: #111827 !important;
    font-size: 21px !important;
    line-height: 1.46 !important;
    letter-spacing: -0.035em !important;
    font-weight: 850 !important;
  }

  .CLAUDETOK_p {
    margin: 13px 0 !important;
    color: #263241 !important;
    font-size: 16.5px !important;
    line-height: 1.9 !important;
    font-weight: 500 !important;
  }

  .CLAUDETOK_toc {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 12px !important;
    margin-top: 18px !important;
  }

  .CLAUDETOK_toc a {
    display: block !important;
    padding: 15px 16px !important;
    border: 1px solid #dbeafe !important;
    border-radius: 16px !important;
    background: #f8fafc !important;
    color: #1d4ed8 !important;
    text-decoration: none !important;
    font-size: 15px !important;
    font-weight: 850 !important;
    line-height: 1.5 !important;
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease !important;
  }

  .CLAUDETOK_toc a:hover {
    transform: translateY(-2px) !important;
    border-color: #93c5fd !important;
    box-shadow: 0 12px 24px rgba(37, 99, 235, 0.12) !important;
  }

  .CLAUDETOK_table {
    width: 100% !important;
    border-collapse: collapse !important;
    margin: 20px 0 !important;
    overflow: hidden !important;
    border-radius: 18px !important;
    box-shadow: 0 0 0 1px #e5e7eb !important;
    font-size: 15px !important;
    background: #ffffff !important;
  }

  .CLAUDETOK_table th,
  .CLAUDETOK_table td {
    padding: 15px 14px !important;
    border-bottom: 1px solid #e5e7eb !important;
    vertical-align: top !important;
    text-align: left !important;
    color: #1f2937 !important;
    line-height: 1.72 !important;
  }

  .CLAUDETOK_table th {
    background: #eef2ff !important;
    color: #111827 !important;
    font-weight: 900 !important;
  }

  .CLAUDETOK_table tr:last-child td {
    border-bottom: 0 !important;
  }

  .CLAUDETOK_code {
    display: block !important;
    margin: 20px 0 !important;
    padding: 20px !important;
    border-radius: 18px !important;
    border: 1px solid #334155 !important;
    background: #0f172a !important;
    color: #f8fafc !important;
    overflow-x: auto !important;
    font-family: &quot;Cascadia Code&quot;, &quot;Consolas&quot;, &quot;Courier New&quot;, monospace !important;
    font-size: 14.5px !important;
    line-height: 1.78 !important;
    white-space: pre-wrap !important;
    word-break: break-word !important;
    box-shadow: 0 14px 32px rgba(15, 23, 42, 0.22) !important;
  }

  .CLAUDETOK_code code,
  pre.CLAUDETOK_code code,
  .CLAUDETOK_wrap pre code {
    color: #f8fafc !important;
    background: transparent !important;
    font-family: &quot;Cascadia Code&quot;, &quot;Consolas&quot;, &quot;Courier New&quot;, monospace !important;
    font-size: 14.5px !important;
    line-height: 1.78 !important;
    opacity: 1 !important;
    text-shadow: none !important;
  }

  .CLAUDETOK_list {
    margin: 16px 0 !important;
    padding: 0 !important;
    list-style: none !important;
  }

  .CLAUDETOK_list li {
    position: relative !important;
    margin: 10px 0 !important;
    padding: 14px 14px 14px 44px !important;
    border: 1px solid #e5e7eb !important;
    border-radius: 16px !important;
    background: #ffffff !important;
    color: #263241 !important;
    font-size: 15.8px !important;
    line-height: 1.72 !important;
    font-weight: 500 !important;
  }

  .CLAUDETOK_list li::before {
    content: &quot;✓&quot; !important;
    position: absolute !important;
    left: 15px !important;
    top: 14px !important;
    width: 21px !important;
    height: 21px !important;
    border-radius: 50% !important;
    background: #4f46e5 !important;
    color: #ffffff !important;
    text-align: center !important;
    line-height: 21px !important;
    font-weight: 900 !important;
    font-size: 12px !important;
  }

  .CLAUDETOK_quote {
    margin: 24px 0 !important;
    padding: 19px 21px !important;
    border-left: 6px solid #0ea5e9 !important;
    border-radius: 16px !important;
    background: #f0f9ff !important;
    color: #0f172a !important;
    font-size: 16px !important;
    line-height: 1.82 !important;
    font-weight: 800 !important;
  }

  .CLAUDETOK_note {
    margin-top: 14px !important;
    padding: 15px 17px !important;
    border-radius: 16px !important;
    background: #fefce8 !important;
    border: 1px solid #fde68a !important;
    color: #713f12 !important;
    font-size: 14.5px !important;
    line-height: 1.72 !important;
    font-weight: 700 !important;
  }

  .CLAUDETOK_tagbox {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    margin-top: 14px !important;
  }

  .CLAUDETOK_tagbox span {
    padding: 8px 12px !important;
    border-radius: 999px !important;
    background: #eef2ff !important;
    color: #3730a3 !important;
    font-size: 13px !important;
    font-weight: 850 !important;
  }

  .CLAUDETOK_btnTop {
    position: fixed !important;
    right: 18px !important;
    bottom: 22px !important;
    z-index: 9999 !important;
    display: none;
    padding: 11px 14px !important;
    border: 0 !important;
    border-radius: 999px !important;
    background: #111827 !important;
    color: #ffffff !important;
    font-size: 13px !important;
    font-weight: 800 !important;
    cursor: pointer !important;
    box-shadow: 0 14px 30px rgba(15, 23, 42, 0.22) !important;
  }

  .CLAUDETOK_progress {
    position: fixed !important;
    left: 0 !important;
    top: 0 !important;
    z-index: 99999 !important;
    width: 0;
    height: 4px !important;
    background: linear-gradient(90deg, #4f46e5, #0ea5e9) !important;
  }

  @media (max-width: 760px) {
    .CLAUDETOK_wrap {
      padding: 16px 12px 40px !important;
    }

    .CLAUDETOK_hero {
      padding: 34px 22px !important;
      border-radius: 22px !important;
    }

    .CLAUDETOK_h1 {
      font-size: 30px !important;
      line-height: 1.25 !important;
    }

    .CLAUDETOK_lead {
      font-size: 15.8px !important;
    }

    .CLAUDETOK_toc {
      grid-template-columns: 1fr !important;
    }

    .CLAUDETOK_table {
      display: block !important;
      overflow-x: auto !important;
      white-space: nowrap !important;
    }

    .CLAUDETOK_h2 {
      font-size: 23px !important;
      line-height: 1.42 !important;
    }

    .CLAUDETOK_code {
      font-size: 13.5px !important;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;div id=&quot;CLAUDETOK_progress&quot; class=&quot;CLAUDETOK_progress&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;article class=&quot;CLAUDETOK_wrap&quot;&gt;
&lt;section class=&quot;CLAUDETOK_hero&quot;&gt;&lt;span class=&quot;CLAUDETOK_badge&quot;&gt;Claude AI 사용량 줄이는 현실적인 방법&lt;/span&gt;
&lt;h1 class=&quot;CLAUDETOK_h1&quot;&gt;Claude AI 토큰, 생각보다 빨리 줄어든다면 이렇게 써보세요&lt;/h1&gt;
&lt;p class=&quot;CLAUDETOK_lead&quot; data-ke-size=&quot;size16&quot;&gt;Claude AI나 Claude Code를 쓰다 보면 &amp;ldquo;분명 별로 안 쓴 것 같은데 왜 벌써 사용량이 줄었지?&amp;rdquo;라는 생각이 들 때가 있습니다. 저도 개발 작업에 Claude를 붙여 쓰면서 가장 많이 신경 쓰게 된 부분이 바로 토큰과 컨텍스트 관리였습니다. 그래서 이번 글에서는 어렵게 설명하기보다, 실제로 바로 적용할 수 있는 방식으로 Claude 토큰을 아끼는 방법을 정리해보려고 합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;CLAUDETOK_thumbnail&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PHkxq/dJMcadaJtxS/XHxTNTjGtYqQw7AOZRZau1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PHkxq/dJMcadaJtxS/XHxTNTjGtYqQw7AOZRZau1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PHkxq/dJMcadaJtxS/XHxTNTjGtYqQw7AOZRZau1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPHkxq%2FdJMcadaJtxS%2FXHxTNTjGtYqQw7AOZRZau1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;CLAUDETOK_thumbnail_caption&quot;&gt;Claude AI를 더 오래, 더 효율적으로 쓰기 위한 토큰 관리 방법&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;CLAUDETOK_box CLAUDETOK_box_blue&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; style=&quot;margin-top: 0 !important;&quot; data-ke-size=&quot;size26&quot;&gt;먼저 결론부터 이야기하면&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude 토큰을 아끼는 가장 좋은 방법은 단순히 질문을 짧게 쓰는 것이 아닙니다. 더 중요한 것은 Claude가 매번 다시 읽어야 하는 내용을 줄이는 것입니다.&lt;/p&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude는 질문 하나만 보는 것이 아니라 이전 대화, 읽은 파일, 명령 실행 결과, 로그, 설정 파일, MCP 도구 정보까지 함께 참고할 수 있습니다. 그래서 대화가 길어지고 파일을 많이 읽을수록 토큰 사용량은 자연스럽게 늘어납니다.&lt;/p&gt;
&lt;div class=&quot;CLAUDETOK_quote&quot;&gt;쉽게 말하면, Claude에게 계속 두꺼운 참고자료를 들고 일하라고 시키면 그만큼 에너지를 더 쓰게 됩니다. 토큰 절약의 핵심은 &amp;ldquo;필요한 자료만 얇고 정확하게 건네주는 것&amp;rdquo;입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;CLAUDETOK_box&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; style=&quot;margin-top: 0 !important;&quot; data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;div class=&quot;CLAUDETOK_toc&quot;&gt;&lt;a href=&quot;#CLAUDETOK_sec01&quot;&gt;1. 토큰이 빨리 줄어드는 이유&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec02&quot;&gt;2. Claude Code에서 꼭 쓰면 좋은 명령어&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec03&quot;&gt;3. 질문을 어떻게 써야 토큰을 아낄 수 있을까?&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec04&quot;&gt;4. 모델 선택도 비용 관리다&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec05&quot;&gt;5. CLAUDE.md는 짧고 정확하게&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec06&quot;&gt;6. MCP와 로그는 조심해서 쓰기&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec07&quot;&gt;7. 프롬프트 캐싱은 언제 좋을까?&lt;/a&gt; &lt;a href=&quot;#CLAUDETOK_sec08&quot;&gt;8. 실전 체크리스트&lt;/a&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec01&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;1. Claude 토큰이 빨리 줄어드는 이유&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude를 사용할 때 토큰은 내가 입력한 질문에만 쓰이는 것이 아닙니다. Claude가 답변을 만들기 위해 참고하는 전체 문맥에 토큰이 사용됩니다.&lt;/p&gt;
&lt;table class=&quot;CLAUDETOK_table&quot; 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;왜 조심해야 하나?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;질문 내용&lt;/td&gt;
&lt;td&gt;내가 Claude에게 직접 입력한 문장&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;Claude Code가 읽은 소스코드, 문서, 설정 파일&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;MCP 도구 정보&lt;/td&gt;
&lt;td&gt;외부 도구, DB, API 연결 정보&lt;/td&gt;
&lt;td&gt;필요 없는 도구까지 켜두면 컨텍스트 관리가 복잡해질 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;CLAUDETOK_box CLAUDETOK_box_yellow&quot;&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; style=&quot;margin-top: 0 !important;&quot; data-ke-size=&quot;size23&quot;&gt;제가 느낀 가장 큰 낭비 포인트&lt;/h3&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;가장 큰 낭비는 &amp;ldquo;Claude가 뭘 봐야 할지 모르는 상태&amp;rdquo;에서 작업을 시작할 때 생깁니다. 예를 들어 &amp;ldquo;프로젝트 전체 확인해서 오류 고쳐줘&amp;rdquo;라고 하면 Claude는 관련 없는 파일까지 탐색할 가능성이 큽니다. 반대로 &amp;ldquo;이 로그인 오류는 Login.tsx와 authService.ts 쪽 문제 같아. 이 두 파일 중심으로 봐줘&amp;rdquo;라고 하면 훨씬 효율적입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec02&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;2. Claude Code에서 꼭 쓰면 좋은 명령어&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude Code를 사용한다면 아래 명령어들은 꼭 알아두는 것이 좋습니다. 특히 개발 작업을 오래 하다 보면 세션이 길어지고, 파일도 많이 읽고, 테스트 로그도 누적되기 때문에 사용량 관리가 중요해집니다.&lt;/p&gt;
&lt;table class=&quot;CLAUDETOK_table&quot; 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;이럴 때 사용하면 좋음&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;/usage&lt;/b&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;b&gt;/context&lt;/b&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;b&gt;/clear&lt;/b&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;b&gt;/compact&lt;/b&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;b&gt;/model&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;사용할 Claude 모델을 변경합니다.&lt;/td&gt;
&lt;td&gt;간단한 작업과 복잡한 작업의 모델을 나누고 싶을 때 좋습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;/effort&lt;/b&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;b&gt;/mcp&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;MCP 서버 연결 상태를 관리합니다.&lt;/td&gt;
&lt;td&gt;외부 도구 연결이 많을 때 점검용으로 좋습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;실제로 이렇게 쓰면 편합니다&lt;/h3&gt;
&lt;pre class=&quot;CLAUDETOK_code jboss-cli&quot;&gt;&lt;code&gt;# 현재 사용량 확인
/usage

# 현재 컨텍스트가 얼마나 찼는지 확인
/context

# 완전히 다른 작업을 시작할 때
/clear

# 같은 작업을 이어가되 문맥을 줄이고 싶을 때
/compact 지금까지 수정한 파일, 남은 작업, 주의할 점 중심으로 요약해줘

# 모델 변경
/model sonnet

# 간단한 작업이면 추론 강도 낮추기
/effort medium&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;CLAUDETOK_note&quot;&gt;개인적으로는 새 기능 개발을 시작하기 전에 /clear, 긴 작업 중간에는 /compact, 사용량이 이상하게 빨리 줄어든다고 느낄 때는 /context를 먼저 확인하는 방식이 가장 편했습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec03&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;3. 질문을 어떻게 써야 토큰을 아낄 수 있을까?&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude에게 질문할 때는 짧게 쓰는 것보다 정확하게 쓰는 것이 훨씬 중요합니다. 질문이 짧아도 모호하면 Claude가 여러 방향으로 추측해야 하고, 그 과정에서 파일을 더 많이 읽거나 답변을 여러 번 다시 만들게 됩니다.&lt;/p&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;아쉬운 요청 예시&lt;/h3&gt;
&lt;pre class=&quot;CLAUDETOK_code erlang&quot;&gt;&lt;code&gt;이 프로젝트 전체적으로 오류 좀 고쳐줘.
성능도 개선하고 코드도 정리해줘.&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;이런 요청은 사람에게 말해도 범위가 너무 넓습니다. Claude 입장에서도 어디부터 봐야 할지 애매하기 때문에 불필요한 탐색이 늘어날 수 있습니다.&lt;/p&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;좋은 요청 예시&lt;/h3&gt;
&lt;pre class=&quot;CLAUDETOK_code markdown&quot;&gt;&lt;code&gt;목표 : 로그인 화면에서 아이디와 비밀번호를 입력하지 않았을 때 안내 문구를 보여주고 싶어.

확인할 파일 :
- src/pages/Login.tsx
- src/services/authService.ts

조건 :
- API 응답 구조는 바꾸지 말 것
- 기존 디자인 톤은 유지할 것
- 관련 없는 파일은 수정하지 말 것

결과물 :
1. 수정한 코드
2. 수정한 파일 목록
3. 왜 이렇게 바꿨는지 설명
4. 실행해야 할 테스트 명령어&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 적으면 Claude가 봐야 할 범위가 줄어듭니다. 결국 토큰을 아끼는 질문은 &amp;ldquo;적게 말하는 질문&amp;rdquo;이 아니라 &amp;ldquo;헷갈리지 않게 말하는 질문&amp;rdquo;입니다.&lt;/p&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;프롬프트에 넣으면 좋은 항목&lt;/h3&gt;
&lt;ul class=&quot;CLAUDETOK_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;목표 : &lt;/b&gt; 무엇을 해결하고 싶은지 한 문장으로 적습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;범위 : &lt;/b&gt; 확인해야 할 파일, 폴더, 기능명을 알려줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제외 조건 : &lt;/b&gt; 건드리면 안 되는 파일이나 정책을 적습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력 형식 : &lt;/b&gt; 코드, 요약, 표, 체크리스트 등 원하는 형태를 지정합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;검증 방법 : &lt;/b&gt; 테스트 명령어, 기대 결과, 화면 조건을 알려줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec04&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;4. 모델 선택도 비용 관리다&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude를 쓸 때 무조건 가장 강력한 모델만 쓰는 것이 정답은 아닙니다. 복잡한 설계나 깊은 분석에는 고성능 모델이 좋지만, 단순한 문서 정리나 작은 코드 수정까지 전부 고성능 모델로 처리하면 효율이 떨어질 수 있습니다.&lt;/p&gt;
&lt;table class=&quot;CLAUDETOK_table&quot; 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;이유&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&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;Sonnet 계열 중심&lt;/td&gt;
&lt;td&gt;속도와 품질의 균형이 좋습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;복잡한 장애 분석, 구조 설계&lt;/td&gt;
&lt;td&gt;Opus 계열 또는 높은 effort&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;div class=&quot;CLAUDETOK_quote&quot;&gt;제가 추천하는 방식은 처음부터 최고 모델로 끝까지 가는 방식이 아닙니다. 먼저 일반 모델로 범위를 잡고, 진짜 어려운 판단이 필요한 순간에만 강한 모델을 쓰는 방식이 더 현실적입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec05&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;5. CLAUDE.md는 짧고 정확하게 관리하기&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude Code를 쓰다 보면 프로젝트 루트에 CLAUDE.md 파일을 만들어 프로젝트 규칙을 적어두는 경우가 많습니다. 이 파일은 굉장히 유용하지만, 너무 길게 쓰면 오히려 매번 Claude가 읽어야 하는 기본 정보가 많아질 수 있습니다.&lt;/p&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;좋은 CLAUDE.md의 기준&lt;/h3&gt;
&lt;ul class=&quot;CLAUDETOK_list&quot; 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;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;CLAUDE.md 예시&lt;/h3&gt;
&lt;pre class=&quot;CLAUDETOK_code markdown&quot;&gt;&lt;code&gt;# Project Guide

## Stack
- Frontend : React + TypeScript
- Backend : Node.js + Express
- Database : PostgreSQL

## Rules
- API 응답 구조는 임의로 변경하지 않는다.
- 기존 class naming 규칙을 유지한다.
- 작업 전 관련 파일을 먼저 확인하고, 최소 범위만 수정한다.
- 수정 후 변경 파일 목록과 테스트 명령어를 설명한다.

## Commands
- npm run lint
- npm run test
- npm run build&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 간단합니다. Claude가 매번 알아야 하는 정보만 CLAUDE.md에 두고, 나머지는 필요할 때만 불러오는 방식이 좋습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec06&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;6. MCP와 로그는 필요한 만큼만 쓰기&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;MCP는 Claude Code를 외부 도구, 데이터베이스, API, 이슈 트래커와 연결할 수 있게 해주는 강력한 기능입니다. 하지만 도구를 많이 연결한다고 무조건 좋은 것은 아닙니다. 현재 작업과 관련 없는 도구까지 많이 켜져 있으면 컨텍스트가 복잡해지고, 분석해야 할 정보도 늘어날 수 있습니다.&lt;/p&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;MCP 사용 시 기억할 점&lt;/h3&gt;
&lt;ul class=&quot;CLAUDETOK_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 작업에 필요 없는 MCP 서버는 꺼둡니다.&lt;/li&gt;
&lt;li&gt;DB 전체 스키마보다 관련 테이블만 알려줍니다.&lt;/li&gt;
&lt;li&gt;이슈 전체 목록보다 관련 이슈 번호를 지정합니다.&lt;/li&gt;
&lt;li&gt;도구 결과가 너무 길게 나오지 않도록 제한합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;로그 분석도 똑같습니다&lt;/h3&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;에러를 찾겠다고 서버 로그 전체를 Claude에게 넘기는 것은 비효율적입니다. 대부분은 최근 에러, 실패 구간, 예외 메시지 주변만 봐도 충분한 경우가 많습니다.&lt;/p&gt;
&lt;pre class=&quot;CLAUDETOK_code 1c&quot;&gt;&lt;code&gt;# 비효율적인 방식
전체 app.log 파일을 그대로 붙여넣기

# 조금 더 나은 방식
grep -i &quot;error\|fail\|exception&quot; app.log | tail -100

# 테스트 실패 부분만 보고 싶을 때
npm test 2&amp;gt;&amp;amp;1 | grep -A 5 -E &quot;FAIL|ERROR|Exception&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;CLAUDETOK_note&quot;&gt;로그는 많이 줄수록 좋은 것이 아니라, 원인에 가까운 부분만 주는 것이 좋습니다. Claude도 사람처럼 잡음이 많으면 핵심을 찾는 데 더 많은 비용이 듭니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec07&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;7. 프롬프트 캐싱은 언제 좋을까?&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;프롬프트 캐싱은 같은 지시문, 같은 문서, 같은 예제, 같은 배경 설명을 반복해서 사용할 때 효과가 있습니다. 특히 API로 Claude를 직접 사용하는 경우라면 캐싱 전략을 잘 설계하는 것만으로도 비용과 응답 속도 면에서 도움이 될 수 있습니다.&lt;/p&gt;
&lt;table class=&quot;CLAUDETOK_table&quot; 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;항상 같은 시스템 프롬프트를 사용하는 경우&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;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API 기반 자동화 워크플로우를 만드는 경우&lt;/td&gt;
&lt;td&gt;Claude 웹 화면에서 간단히 질문하는 정도인 경우&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;같은 코드베이스 규칙을 계속 주입하는 경우&lt;/td&gt;
&lt;td&gt;매번 다른 프로젝트를 짧게 확인하는 경우&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;CLAUDETOK_box CLAUDETOK_box_dark&quot;&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; style=&quot;color: #ffffff !important; margin-top: 0 !important;&quot; data-ke-size=&quot;size23&quot;&gt;개발자라면 이렇게 생각하면 쉽습니다&lt;/h3&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; style=&quot;color: #f8fafc !important;&quot; data-ke-size=&quot;size16&quot;&gt;반복되는 긴 입력은 캐싱하고, 단순 작업은 가벼운 모델로 보내고, 긴 로그는 미리 줄이고, 복잡한 판단만 강한 모델에게 맡기는 구조가 좋습니다. AI 사용량 최적화는 결국 &amp;ldquo;입력을 어떻게 설계하느냐&amp;rdquo;의 문제에 가깝습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;CLAUDETOK_sec08&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;8. 바로 적용할 수 있는 실전 체크리스트&lt;/h2&gt;
&lt;table class=&quot;CLAUDETOK_table&quot; 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;사용하면 좋은 방법&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;새로운 작업을 시작할 때&lt;/td&gt;
&lt;td&gt;이전 문맥이 필요 없으면 새로 시작합니다.&lt;/td&gt;
&lt;td&gt;/clear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;작업이 길어졌을 때&lt;/td&gt;
&lt;td&gt;중요 내용 중심으로 요약합니다.&lt;/td&gt;
&lt;td&gt;/compact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용량이 빨리 줄어드는 느낌이 들 때&lt;/td&gt;
&lt;td&gt;현재 컨텍스트 사용량을 확인합니다.&lt;/td&gt;
&lt;td&gt;/context, /usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;간단한 코드 수정&lt;/td&gt;
&lt;td&gt;일반 모델과 낮은 effort를 사용합니다.&lt;/td&gt;
&lt;td&gt;/model, /effort medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;복잡한 설계나 장애 분석&lt;/td&gt;
&lt;td&gt;강한 모델을 잠깐 사용합니다.&lt;/td&gt;
&lt;td&gt;Opus 계열 또는 high effort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;로그 분석&lt;/td&gt;
&lt;td&gt;전체 로그가 아니라 실패 부분만 전달합니다.&lt;/td&gt;
&lt;td&gt;grep, tail, 에러 필터링&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;프로젝트 규칙 관리&lt;/td&gt;
&lt;td&gt;CLAUDE.md를 짧게 유지합니다.&lt;/td&gt;
&lt;td&gt;핵심 규칙만 작성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP 사용&lt;/td&gt;
&lt;td&gt;필요한 MCP만 연결합니다.&lt;/td&gt;
&lt;td&gt;/mcp, /context&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;마무리 : Claude를 오래 잘 쓰려면 컨텍스트 관리가 핵심입니다&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude AI를 잘 쓰는 사람은 질문을 무조건 짧게 쓰는 사람이 아닙니다. Claude가 정확히 필요한 것만 보고 판단할 수 있게 정리해주는 사람입니다.&lt;/p&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;특히 Claude Code를 개발에 사용한다면 /usage, /context, /clear, /compact, /model, /effort 같은 명령어는 꼭 익혀두는 것이 좋습니다. 여기에 CLAUDE.md 정리, 로그 필터링, MCP 최소화, 명확한 프롬프트 작성까지 같이 적용하면 같은 사용량으로 훨씬 더 많은 작업을 처리할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;CLAUDETOK_quote&quot;&gt;결국 토큰을 아끼는 가장 좋은 방법은 Claude에게 일을 덜 시키는 것이 아니라, Claude가 헤매지 않도록 길을 잘 잡아주는 것입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;CLAUDETOK_box&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; style=&quot;margin-top: 0 !important;&quot; data-ke-size=&quot;size26&quot;&gt;참고하면 좋은 공식 문서&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;아래 문서들은 Claude 사용량 관리와 토큰 최적화를 이해할 때 참고하기 좋습니다. Claude는 모델, 요금, 명령어, 정책이 계속 바뀔 수 있으므로 실제 적용 전 공식 문서를 한 번 더 확인하는 것이 좋습니다.&lt;/p&gt;
&lt;ul class=&quot;CLAUDETOK_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Claude Code Commands : &lt;/b&gt; /clear, /compact, /context, /usage, /model, /effort 등 명령어 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Claude Prompt Caching : &lt;/b&gt; 반복 프롬프트와 긴 컨텍스트 비용 절감 방식 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Claude Pricing : &lt;/b&gt; 모델별 입력 토큰, 출력 토큰, 캐시 비용 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Claude MCP : &lt;/b&gt; 외부 도구, DB, API 연결 방식 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Reddit r/ClaudeCode : &lt;/b&gt; 실제 사용자들의 토큰 사용 경험과 팁 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section class=&quot;CLAUDETOK_box CLAUDETOK_box_blue&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; style=&quot;margin-top: 0 !important;&quot; data-ke-size=&quot;size26&quot;&gt;글 제목 추천&lt;/h2&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1안 : &lt;/b&gt; Claude AI 토큰 아끼는 법 : Claude Code 사용량 줄이는 현실적인 방법&lt;/p&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2안 : &lt;/b&gt; Claude Code 토큰이 빨리 줄어든다면? 사용량 줄이는 설정과 팁 정리&lt;/p&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3안 : &lt;/b&gt; Claude AI를 오래 쓰는 방법 : 토큰 절약과 컨텍스트 관리 실전 가이드&lt;/p&gt;
&lt;h3 class=&quot;CLAUDETOK_h3&quot; data-ke-size=&quot;size23&quot;&gt;SEO 설명 문구&lt;/h3&gt;
&lt;p class=&quot;CLAUDETOK_p&quot; data-ke-size=&quot;size16&quot;&gt;Claude AI와 Claude Code를 사용할 때 토큰을 효율적으로 아끼는 방법을 정리했습니다. /usage, /context, /clear, /compact, /model, /effort 명령어 사용법부터 CLAUDE.md 관리, MCP 최적화, 프롬프트 캐싱까지 실전 중심으로 설명합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;CLAUDETOK_box&quot;&gt;
&lt;h2 class=&quot;CLAUDETOK_h2&quot; data-ke-size=&quot;size26&quot;&gt;이 글의 핵심 키워드&lt;/h2&gt;
&lt;div class=&quot;CLAUDETOK_tagbox&quot;&gt;&lt;span&gt;Claude AI 토큰 절약 방법&lt;/span&gt; &lt;span&gt;Claude Code 사용량 줄이기&lt;/span&gt; &lt;span&gt;Claude Code context 관리&lt;/span&gt; &lt;span&gt;Claude Code clear compact 사용법&lt;/span&gt; &lt;span&gt;Claude 프롬프트 캐싱&lt;/span&gt; &lt;span&gt;Claude Code MCP 토큰&lt;/span&gt; &lt;span&gt;CLAUDE.md 작성법&lt;/span&gt; &lt;span&gt;Claude Code 모델 선택&lt;/span&gt; &lt;span&gt;AI 코딩 도구 비용 절감&lt;/span&gt; &lt;span&gt;Claude Code 토큰 최적화&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;/article&gt;
&lt;p&gt;&lt;button id=&quot;CLAUDETOK_btnTop&quot; class=&quot;CLAUDETOK_btnTop&quot; type=&quot;button&quot;&gt;위로&lt;/button&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  (function () {
    const CLAUDETOK_btnTop = document.getElementById(&quot;CLAUDETOK_btnTop&quot;);
    const CLAUDETOK_progress = document.getElementById(&quot;CLAUDETOK_progress&quot;);

    function CLAUDETOK_onScroll() {
      const CLAUDETOK_scrollTop = window.scrollY || document.documentElement.scrollTop;
      const CLAUDETOK_docHeight = document.documentElement.scrollHeight - window.innerHeight;
      const CLAUDETOK_percent = CLAUDETOK_docHeight &gt; 0 ? (CLAUDETOK_scrollTop / CLAUDETOK_docHeight) * 100 : 0;

      if (CLAUDETOK_progress) {
        CLAUDETOK_progress.style.width = CLAUDETOK_percent + &quot;%&quot;;
      }

      if (CLAUDETOK_btnTop) {
        CLAUDETOK_btnTop.style.display = CLAUDETOK_scrollTop &gt; 500 ? &quot;block&quot; : &quot;none&quot;;
      }
    }

    if (CLAUDETOK_btnTop) {
      CLAUDETOK_btnTop.addEventListener(&quot;click&quot;, function () {
        window.scrollTo({ top: 0, behavior: &quot;smooth&quot; });
      });
    }

    window.addEventListener(&quot;scroll&quot;, CLAUDETOK_onScroll);
    CLAUDETOK_onScroll();
  })();
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>ai개발도구</category>
      <category>AI토큰절약</category>
      <category>anthropic claude</category>
      <category>claudeai</category>
      <category>claudecode</category>
      <category>Claude사용법</category>
      <category>Claude토큰</category>
      <category>개발자생산성</category>
      <category>클로드코드</category>
      <category>프롬프트엔지니어링</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/583</guid>
      <comments>https://odinbox.tistory.com/583#entry583comment</comments>
      <pubDate>Fri, 1 May 2026 09:44:17 +0900</pubDate>
    </item>
    <item>
      <title>Sentry 완벽 가이드, 에러 추적부터 성능 모니터링까지</title>
      <link>https://odinbox.tistory.com/582</link>
      <description>&lt;div id=&quot;SENTRY_docsRoot&quot; class=&quot;SENTRY_docsRoot&quot;&gt;
&lt;div id=&quot;SENTRY_readProgress&quot; class=&quot;SENTRY_readProgress&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;section id=&quot;SENTRY_docsHero&quot; class=&quot;SENTRY_docsHero&quot;&gt;
&lt;div class=&quot;SENTRY_docsHeroGrid&quot;&gt;
&lt;div class=&quot;SENTRY_docsHeroContent&quot;&gt;
&lt;div class=&quot;SENTRY_docsEyebrow&quot;&gt;SENTRY OBSERVABILITY GUIDE&lt;/div&gt;
&lt;h1 class=&quot;SENTRY_docsHeroTitle&quot;&gt;Sentry 완벽 가이드:&lt;br /&gt;에러 추적부터 성능 모니터링까지&lt;/h1&gt;
&lt;p class=&quot;SENTRY_docsHeroText&quot; data-ke-size=&quot;size16&quot;&gt;React, ASP.NET Core, API 서버 환경에서 Sentry를 활용해 운영 장애, 성능 병목, 사용자 오류 흐름, Source Map, Session Replay, 샘플링 전략까지 정리한 실무 중심 가이드입니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsHeroMeta&quot;&gt;
&lt;div&gt;&lt;span&gt;대상&lt;/span&gt; &lt;b&gt;Frontend &amp;middot; Backend&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;핵심&lt;/span&gt; &lt;b&gt;Error &amp;middot; Tracing &amp;middot; Replay&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;운영&lt;/span&gt; &lt;b&gt;Release &amp;middot; Sampling &amp;middot; Security&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsThumbPanel&quot;&gt;
&lt;div class=&quot;SENTRY_docsThumbCard&quot;&gt;
&lt;div class=&quot;SENTRY_docsThumbTop&quot;&gt;&lt;span&gt;Official Docs Style&lt;/span&gt; &lt;b&gt;Sentry&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsThumbImage&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN7e2M/dJMcaaSDkfq/GE7IsNd1nwTXOQGm4GZdHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN7e2M/dJMcaaSDkfq/GE7IsNd1nwTXOQGm4GZdHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN7e2M/dJMcaaSDkfq/GE7IsNd1nwTXOQGm4GZdHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN7e2M%2FdJMcaaSDkfq%2FGE7IsNd1nwTXOQGm4GZdHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsThumbBottom&quot;&gt;&lt;b&gt;Observability&lt;/b&gt; &lt;span&gt;Error Monitoring &amp;middot; Performance &amp;middot; Source Map &amp;middot; Replay&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;main class=&quot;SENTRY_docsMain&quot;&gt;
&lt;section id=&quot;SENTRY_sectionIntro&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Introduction&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;1. Sentry는 무엇인가&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry는 애플리케이션에서 발생하는 오류와 성능 문제를 개발자가 빠르게 분석할 수 있도록 도와주는 관측성 플랫폼입니다. 단순히 로그를 저장하는 수준이 아니라, 어떤 사용자에게, 어떤 화면에서, 어떤 릴리스 이후, 어떤 코드 라인에서 문제가 발생했는지 추적할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;전통적인 서버 모니터링이 CPU, 메모리, 디스크, 네트워크 같은 인프라 상태를 보는 데 집중했다면, Sentry는 실제 애플리케이션 코드와 사용자 경험에 더 가깝습니다. 프론트엔드 런타임 오류, API 실패, 느린 요청, 소스맵 기반 원본 코드 추적, 세션 리플레이 등을 통해 운영 장애 대응 속도를 높일 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsInfoGrid&quot;&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;01&lt;/span&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;에러 추적&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unhandled Exception, API 실패, 런타임 오류를 자동 수집합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;02&lt;/span&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;성능 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션, 스팬, 느린 API, DB 병목을 추적합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;03&lt;/span&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;/div&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;04&lt;/span&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;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionArchitecture&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Architecture&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;2. Sentry 내부 아키텍처 흐름&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry는 SDK에서 전송된 이벤트를 바로 저장하지 않고 여러 처리 단계를 거칩니다. 대표적으로 SDK, Relay, Kafka, Ingest Consumer, Symbolicator, Snuba, ClickHouse가 이벤트 수집과 분석 과정에 관여합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsFlow&quot;&gt;
&lt;div&gt;&lt;b&gt;SDK&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저, 모바일, 서버 런타임에서 에러와 성능 이벤트를 수집합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Relay&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DSN 검증, 할당량 체크, 샘플링, 이벤트 필터링을 수행합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Kafka&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대량 이벤트를 비동기 스트리밍 방식으로 안정적으로 전달합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Symbolicator&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난독화된 스택 트레이스를 원본 소스 코드 라인으로 복원합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Snuba / ClickHouse&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 검색, 집계, 대시보드 분석을 위한 데이터를 저장합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsCallout&quot;&gt;&lt;b&gt;실무 핵심&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sentry는 인프라 전체를 보는 도구라기보다 애플리케이션 코드와 사용자 경험 중심의 모니터링 도구입니다. 서버 자원 모니터링은 Prometheus, Grafana, Datadog 등과 함께 구성하는 방식이 안정적입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionFrontend&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Frontend&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;3. React 프론트엔드 적용 방법&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;React에서는 애플리케이션 진입점에서 Sentry를 초기화하고, Error Boundary, Browser Tracing, Session Replay를 함께 구성하는 방식이 일반적입니다. 운영 환경에서는 성능 트레이스 수집 비율을 낮게 설정하여 비용과 노이즈를 줄여야 합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;React / Vite 기본 적용 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import * as Sentry from &quot;@sentry/react&quot;;

Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  environment: import.meta.env.MODE,
  release: `frontend@${import.meta.env.VITE_APP_VERSION}`,

  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.replayIntegration()
  ],

  sampleRate: 1.0,
  tracesSampleRate: import.meta.env.MODE === &quot;production&quot; ? 0.05 : 1.0,

  replaysSessionSampleRate: 0.0,
  replaysOnErrorSampleRate: 1.0,

  beforeSend(SENTRY_event) {
    if (SENTRY_event.user) {
      delete SENTRY_event.user.email;
      delete SENTRY_event.user.ip_address;
    }

    if (SENTRY_event.request &amp;amp;&amp;amp; SENTRY_event.request.headers) {
      delete SENTRY_event.request.headers.authorization;
      delete SENTRY_event.request.headers.cookie;
    }

    return SENTRY_event;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;API 오류 수집 전략&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드에서 API 오류를 단순히 콘솔에만 출력하면 운영 환경에서 원인 파악이 어렵습니다. Axios 인터셉터를 사용하면 API 실패 정보를 일관된 방식으로 Sentry에 전송할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;Axios Interceptor 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import axios from &quot;axios&quot;;
import * as Sentry from &quot;@sentry/react&quot;;

const SENTRY_apiClient = axios.create({
  baseURL: &quot;/api&quot;,
  timeout: 10000
});

SENTRY_apiClient.interceptors.response.use(
  function SENTRY_onSuccess(SENTRY_response) {
    return SENTRY_response;
  },
  function SENTRY_onError(SENTRY_error) {
    const SENTRY_status = SENTRY_error.response?.status || &quot;NETWORK&quot;;
    const SENTRY_method = SENTRY_error.config?.method || &quot;UNKNOWN&quot;;
    const SENTRY_url = SENTRY_error.config?.url || &quot;UNKNOWN&quot;;

    Sentry.withScope(function SENTRY_scopeHandler(SENTRY_scope) {
      SENTRY_scope.setTag(&quot;api.status&quot;, String(SENTRY_status));
      SENTRY_scope.setTag(&quot;api.method&quot;, SENTRY_method.toUpperCase());
      SENTRY_scope.setTag(&quot;api.url&quot;, SENTRY_url);

      SENTRY_scope.setFingerprint([
        &quot;api-error&quot;,
        SENTRY_method,
        String(SENTRY_status),
        SENTRY_url
      ]);

      Sentry.captureException(SENTRY_error);
    });

    return Promise.reject(SENTRY_error);
  }
);

export default SENTRY_apiClient;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionBackend&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Backend&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;4. ASP.NET Core 백엔드 적용 방법&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;백엔드에서는 Unhandled Exception, 요청 처리 시간, 외부 API 호출 실패, DB 쿼리 병목을 함께 추적하는 것이 중요합니다. 특히 운영 서버에서는 개인정보 전송 여부와 샘플링 비율을 명확하게 통제해야 합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;ASP.NET Core Program.cs 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;var SENTRY_builder = WebApplication.CreateBuilder(args);

SENTRY_builder.WebHost.UseSentry(SENTRY_options =&amp;gt;
{
    SENTRY_options.Dsn = SENTRY_builder.Configuration[&quot;Sentry:Dsn&quot;];
    SENTRY_options.Environment = SENTRY_builder.Environment.EnvironmentName;
    SENTRY_options.Release = &quot;backend@1.0.0&quot;;

    SENTRY_options.TracesSampleRate =
        SENTRY_builder.Environment.IsProduction() ? 0.05 : 1.0;

    SENTRY_options.SendDefaultPii = false;

    SENTRY_options.BeforeSend = SENTRY_event =&amp;gt;
    {
        if (SENTRY_event.User != null)
        {
            SENTRY_event.User.Email = null;
            SENTRY_event.User.IpAddress = null;
        }

        return SENTRY_event;
    };
});

var SENTRY_app = SENTRY_builder.Build();

SENTRY_app.MapGet(&quot;/&quot;, () =&amp;gt; &quot;Sentry backend monitoring ready.&quot;);

SENTRY_app.Run();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionOptions&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;SDK Options&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;5. Sentry 주요 옵션과 편리 기능 정리&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry를 단순히 설치만 하면 운영 환경에서 원하는 수준의 관측성을 얻기 어렵습니다. 실제 서비스에서는 어떤 데이터를 수집할지, 얼마나 수집할지, 어떤 정보는 제거할지, 어떤 오류는 무시할지를 명확하게 설정해야 합니다.&lt;/p&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-1. 기본 식별 옵션&lt;/h3&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;실무 권장값&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dsn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sentry 프로젝트로 이벤트를 전송하기 위한 고유 주소입니다.&lt;/td&gt;
&lt;td&gt;환경변수로 관리하고 코드에 직접 하드코딩하지 않는 것이 좋습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;environment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;production, staging, development 같은 실행 환경을 구분합니다.&lt;/td&gt;
&lt;td&gt;운영, 테스트, 개발 환경을 반드시 분리합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;release&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;어떤 버전에서 오류가 발생했는지 추적합니다.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;frontend@1.0.0&lt;/code&gt;, &lt;code&gt;backend@2026.04.26&lt;/code&gt;처럼 명확히 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;같은 release 안에서 빌드 산출물을 더 세분화합니다.&lt;/td&gt;
&lt;td&gt;모바일 빌드 번호, 웹 빌드 번호, CDN 배포 번호 구분에 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsTip&quot;&gt;&lt;b&gt;실무 팁&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;release 값을 지정하지 않으면 이번 배포 이후 오류가 늘었는지 추적하기 어렵습니다. 운영 배포 자동화에서는 Git Commit SHA, Git Tag, 빌드 번호 중 하나를 release 값으로 넣는 것이 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-2. 에러 수집과 필터링 옵션&lt;/h3&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;주의사항&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sampleRate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;에러 이벤트를 몇 % 수집할지 결정합니다.&lt;/td&gt;
&lt;td&gt;운영 초기에는 &lt;code&gt;1.0&lt;/code&gt;을 권장합니다. 너무 낮추면 중요한 장애를 놓칠 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ignoreErrors&lt;/code&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;code&gt;denyUrls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;특정 URL에서 발생한 오류를 무시합니다.&lt;/td&gt;
&lt;td&gt;광고 스크립트, 브라우저 플러그인, 외부 위젯 오류 제외에 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;allowUrls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;허용한 URL에서 발생한 오류만 수집합니다.&lt;/td&gt;
&lt;td&gt;자사 도메인 오류만 보고 싶을 때 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;beforeSend&lt;/code&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;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;에러 필터링 옵션 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  environment: import.meta.env.MODE,
  release: `frontend@${import.meta.env.VITE_APP_VERSION}`,

  sampleRate: 1.0,

  ignoreErrors: [
    &quot;ResizeObserver loop limit exceeded&quot;,
    &quot;Non-Error promise rejection captured&quot;,
    &quot;Network Error&quot;
  ],

  denyUrls: [
    /extensions\//i,
    /^chrome:\/\//i,
    /^moz-extension:\/\//i,
    /googleads/i,
    /doubleclick/i
  ],

  beforeSend(SENTRY_event, SENTRY_hint) {
    if (SENTRY_event.user) {
      delete SENTRY_event.user.email;
      delete SENTRY_event.user.ip_address;
    }

    if (SENTRY_event.request &amp;amp;&amp;amp; SENTRY_event.request.headers) {
      delete SENTRY_event.request.headers.authorization;
      delete SENTRY_event.request.headers.cookie;
      delete SENTRY_event.request.headers[&quot;x-api-key&quot;];
    }

    const SENTRY_errorMessage = SENTRY_hint.originalException?.message || &quot;&quot;;

    if (SENTRY_errorMessage.includes(&quot;사용자가 직접 취소한 요청&quot;)) {
      return null;
    }

    return SENTRY_event;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-3. 성능 모니터링 옵션&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry의 성능 모니터링은 트랜잭션과 스팬을 통해 화면 로딩, API 요청, DB 처리, 외부 서비스 호출 시간을 추적합니다. 단, 모든 트랜잭션을 100% 수집하면 비용과 노이즈가 빠르게 증가할 수 있으므로 운영 환경에서는 샘플링 전략이 중요합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;권장 사용 방식&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tracesSampleRate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;성능 트랜잭션 수집 비율을 설정합니다.&lt;/td&gt;
&lt;td&gt;운영 환경에서는 &lt;code&gt;0.05&lt;/code&gt; ~ &lt;code&gt;0.1&lt;/code&gt;부터 시작합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tracesSampler&lt;/code&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;code&gt;beforeSendTransaction&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;트랜잭션 전송 직전에 데이터를 수정하거나 폐기합니다.&lt;/td&gt;
&lt;td&gt;health check, static resource 요청을 제외할 때 유용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;동적 트레이싱 샘플링 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,

  integrations: [
    Sentry.browserTracingIntegration()
  ],

  tracesSampler(SENTRY_samplingContext) {
    const SENTRY_transactionName = SENTRY_samplingContext.name || &quot;&quot;;

    if (
      SENTRY_transactionName.includes(&quot;/payment&quot;) ||
      SENTRY_transactionName.includes(&quot;/login&quot;) ||
      SENTRY_transactionName.includes(&quot;/order&quot;)
    ) {
      return 0.5;
    }

    if (SENTRY_transactionName.includes(&quot;/admin&quot;)) {
      return 0.2;
    }

    return 0.05;
  },

  beforeSendTransaction(SENTRY_transaction) {
    if (
      SENTRY_transaction.transaction === &quot;/health&quot; ||
      SENTRY_transaction.transaction === &quot;/ping&quot;
    ) {
      return null;
    }

    return SENTRY_transaction;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsWarning&quot;&gt;&lt;b&gt;주의&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;tracesSampleRate: 1.0&lt;/code&gt;은 모든 성능 이벤트를 수집한다는 의미입니다. 트래픽이 많은 서비스에서 무심코 1.0으로 배포하면 사용량과 비용이 빠르게 증가할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-4. Session Replay 옵션&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Session Replay는 사용자가 오류를 만나기 전후에 어떤 화면을 보고, 어떤 버튼을 누르고, 어떤 네트워크 요청이 실패했는지 재현하는 기능입니다. 텍스트 로그만으로 재현하기 어려운 UI 오류를 분석할 때 매우 유용합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;권장값&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;replaysSessionSampleRate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;일반 사용자 세션을 몇 % 녹화할지 결정합니다.&lt;/td&gt;
&lt;td&gt;운영에서는 &lt;code&gt;0.01&lt;/code&gt; ~ &lt;code&gt;0.05&lt;/code&gt; 또는 &lt;code&gt;0.0&lt;/code&gt;부터 시작합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;replaysOnErrorSampleRate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;오류가 발생한 세션을 몇 % 보관할지 결정합니다.&lt;/td&gt;
&lt;td&gt;오류 분석 목적이라면 &lt;code&gt;1.0&lt;/code&gt; 권장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;maskAllText&lt;/code&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;code&gt;blockAllMedia&lt;/code&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;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;Session Replay 개인정보 보호 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,

  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,
      blockAllMedia: true,

      mask: [
        &quot;.password&quot;,
        &quot;.token&quot;,
        &quot;.phone&quot;,
        &quot;.email&quot;,
        &quot;[data-private='true']&quot;
      ],

      block: [
        &quot;.payment-card-area&quot;,
        &quot;.resident-number-area&quot;,
        &quot;.secret-document-area&quot;
      ]
    })
  ],

  replaysSessionSampleRate: 0.0,
  replaysOnErrorSampleRate: 1.0
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-5. Breadcrumb 활용&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Breadcrumb는 오류가 발생하기 전 사용자가 어떤 행동을 했는지 남기는 작은 로그입니다. 페이지 이동, 버튼 클릭, 콘솔 로그, 네트워크 요청, 사용자 지정 이벤트를 순서대로 확인할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;Breadcrumb 활용 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,

  maxBreadcrumbs: 80,

  beforeBreadcrumb(SENTRY_breadcrumb) {
    if (
      SENTRY_breadcrumb.category === &quot;fetch&quot; ||
      SENTRY_breadcrumb.category === &quot;xhr&quot;
    ) {
      const SENTRY_url = SENTRY_breadcrumb.data?.url || &quot;&quot;;

      if (SENTRY_url.includes(&quot;/auth/token&quot;)) {
        return null;
      }
    }

    return SENTRY_breadcrumb;
  }
});

function SENTRY_onClickOrderButton(SENTRY_orderId) {
  Sentry.addBreadcrumb({
    category: &quot;order&quot;,
    message: &quot;사용자가 주문 버튼을 클릭했습니다.&quot;,
    level: &quot;info&quot;,
    data: {
      orderId: SENTRY_orderId
    }
  });
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-6. Tags, Context, User 활용&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry에서 장애를 빠르게 찾으려면 이벤트에 부가 정보를 잘 넣어야 합니다. tag는 검색과 필터링에 좋고, context는 상세 분석에 좋으며, user는 영향받은 사용자 범위를 파악할 때 유용합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;추천 데이터&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setTag&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;검색과 필터링에 사용할 짧은 값&lt;/td&gt;
&lt;td&gt;화면명, API명, 고객사코드, 기능구분, 배포채널&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setContext&lt;/code&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;code&gt;setUser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;영향받은 사용자 식별&lt;/td&gt;
&lt;td&gt;내부 사용자 ID. 이메일, 전화번호는 신중히 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setExtra&lt;/code&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;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;Tags / Context / User 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;function SENTRY_setMonitoringContext(SENTRY_loginUser) {
  Sentry.setUser({
    id: SENTRY_loginUser.userId,
    username: SENTRY_loginUser.userName
  });

  Sentry.setTag(&quot;company.code&quot;, SENTRY_loginUser.companyCode);
  Sentry.setTag(&quot;system.name&quot;, &quot;IAMZ-BIZ&quot;);
  Sentry.setTag(&quot;screen.name&quot;, &quot;OrderCreatePage&quot;);

  Sentry.setContext(&quot;business&quot;, {
    module: &quot;order&quot;,
    feature: &quot;create-order&quot;,
    permission: SENTRY_loginUser.permissionName
  });
}

function SENTRY_captureOrderError(SENTRY_error, SENTRY_order) {
  Sentry.withScope(function (SENTRY_scope) {
    SENTRY_scope.setTag(&quot;order.status&quot;, SENTRY_order.status);
    SENTRY_scope.setContext(&quot;order&quot;, {
      orderId: SENTRY_order.orderId,
      itemCount: SENTRY_order.items.length,
      totalAmount: SENTRY_order.totalAmount
    });

    Sentry.captureException(SENTRY_error);
  });
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-7. 수동 캡처 편리 함수&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry는 자동 오류 수집뿐 아니라 개발자가 원하는 시점에 직접 메시지, 예외, 트랜잭션 정보를 보낼 수 있습니다. 운영 중 특정 비즈니스 조건이 비정상일 때 수동 캡처를 넣어두면 장애를 더 빨리 찾을 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;수동 캡처 함수 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function SENTRY_validateBusinessRule(SENTRY_payload) {
  if (!SENTRY_payload.customerCode) {
    Sentry.withScope(function (SENTRY_scope) {
      SENTRY_scope.setLevel(&quot;warning&quot;);
      SENTRY_scope.setTag(&quot;validation.type&quot;, &quot;missing-customer-code&quot;);
      SENTRY_scope.setContext(&quot;payload&quot;, {
        screen: &quot;OrderCreatePage&quot;,
        hasItems: SENTRY_payload.items?.length &amp;gt; 0
      });

      Sentry.captureMessage(&quot;주문 생성 요청에 고객사 코드가 없습니다.&quot;);
    });

    return false;
  }

  return true;
}

async function SENTRY_saveOrder(SENTRY_order) {
  try {
    const SENTRY_response = await fetch(&quot;/api/orders&quot;, {
      method: &quot;POST&quot;,
      body: JSON.stringify(SENTRY_order)
    });

    if (!SENTRY_response.ok) {
      throw new Error(&quot;주문 저장 API 실패&quot;);
    }
  } catch (SENTRY_error) {
    Sentry.withScope(function (SENTRY_scope) {
      SENTRY_scope.setTag(&quot;api.name&quot;, &quot;save-order&quot;);
      SENTRY_scope.setTag(&quot;order.status&quot;, SENTRY_order.status);
      SENTRY_scope.setLevel(&quot;error&quot;);

      Sentry.captureException(SENTRY_error);
    });

    throw SENTRY_error;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;5-8. 운영 환경 추천 설정 조합&lt;/h3&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;트레이싱&lt;/th&gt;
&lt;th&gt;리플레이&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;사내 시스템 / 트래픽 낮음&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sampleRate: 1.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tracesSampleRate: 0.2 ~ 1.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;replaysOnErrorSampleRate: 1.0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;일반 B2B 서비스&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sampleRate: 1.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tracesSampleRate: 0.05 ~ 0.2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;일반 세션 낮게, 오류 세션 높게&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;대규모 B2C 서비스&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sampleRate: 0.5 ~ 1.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tracesSampler&lt;/code&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;td&gt;마스킹, 블록 처리 필수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsFinal&quot;&gt;&lt;b&gt;실무 결론&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sentry 옵션 설정의 핵심은 많이 수집하는 것이 아니라 장애 대응에 필요한 데이터를 안전하게 수집하는 것입니다. 운영 환경에서는 에러는 놓치지 않되, 트레이싱과 리플레이는 비용&amp;middot;보안&amp;middot;노이즈를 고려해 점진적으로 확대하는 전략이 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionSourcemap&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Source Maps&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;6. 소스맵과 릴리스 관리&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 코드는 운영 배포 시 압축되고 난독화됩니다. 이 상태에서 오류가 발생하면 스택 트레이스가 실제 원본 코드와 다르게 보일 수 있습니다. 이를 해결하려면 빌드 시점에 Source Map을 생성하고 Sentry에 업로드해야 합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsWarning&quot;&gt;&lt;b&gt;보안 주의&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Source Map은 원본 코드 구조를 노출할 수 있으므로 운영 서버 public 경로에 그대로 남기지 않는 것이 좋습니다. Sentry에 업로드한 뒤 삭제하거나 .map 파일 접근을 차단해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_codeBox&quot;&gt;
&lt;div class=&quot;SENTRY_codeHeader&quot;&gt;&lt;span&gt;Vite Source Map 업로드 예시&lt;/span&gt; &lt;button type=&quot;button&quot;&gt;복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;import { defineConfig } from &quot;vite&quot;;
import react from &quot;@vitejs/plugin-react&quot;;
import { sentryVitePlugin } from &quot;@sentry/vite-plugin&quot;;

export default defineConfig({
  build: {
    sourcemap: &quot;hidden&quot;
  },
  plugins: [
    react(),

    sentryVitePlugin({
      org: &quot;YOUR_ORG_SLUG&quot;,
      project: &quot;YOUR_PROJECT_SLUG&quot;,
      authToken: process.env.SENTRY_AUTH_TOKEN,

      sourcemaps: {
        filesToDeleteAfterUpload: [
          &quot;./dist/**/*.map&quot;
        ]
      }
    })
  ]
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsChecklist&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;릴리스 관리 체크리스트&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프론트엔드와 백엔드 release 값을 명확히 지정합니다.&lt;/li&gt;
&lt;li&gt;production, staging, development environment 값을 분리합니다.&lt;/li&gt;
&lt;li&gt;CI/CD의 SENTRY_AUTH_TOKEN은 Secret으로 관리합니다.&lt;/li&gt;
&lt;li&gt;Source Map은 Sentry 업로드 후 public 배포 경로에서 제거합니다.&lt;/li&gt;
&lt;li&gt;배포 직후 Release 화면에서 신규 오류 증가 여부를 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionTracing&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Tracing&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;7. 분산 트레이싱과 성능 모니터링&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry의 성능 모니터링은 요청 하나를 Transaction으로 보고, 그 안에서 발생하는 API 호출, DB 쿼리, 외부 서비스 호출, 렌더링 작업을 Span 단위로 분석합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsTableWrap&quot;&gt;
&lt;table class=&quot;SENTRY_docsTable&quot; 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;실무 활용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apdex&lt;/td&gt;
&lt;td&gt;사용자 만족도를 0~1 점수로 표현&lt;/td&gt;
&lt;td&gt;서비스 전체 체감 품질 판단&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;p95 / p99&lt;/td&gt;
&lt;td&gt;상위 5% 또는 1% 사용자가 겪는 느린 응답&lt;/td&gt;
&lt;td&gt;일부 사용자만 겪는 병목 추적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;td&gt;분당 또는 초당 요청 처리량&lt;/td&gt;
&lt;td&gt;트래픽 급증과 장애 상관관계 분석&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error Rate&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;/section&gt;
&lt;section id=&quot;SENTRY_sectionSecurity&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Security &amp;amp; Cost&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;8. 도입 시 주의사항: 보안, 비용, 알림&lt;/h2&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;개인정보와 민감정보 제거&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry 이벤트에는 요청 정보, 사용자 정보, 브라우저 정보, 서버 컨텍스트가 포함될 수 있습니다. 이메일, IP, 인증 토큰, 쿠키, 비밀번호, 결제 정보는 전송 전 또는 저장 전 단계에서 반드시 제거해야 합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsInfoGrid SENTRY_docsInfoGridThree&quot;&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;Client&lt;/span&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;beforeSend&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전송 전 user, request, headers, extra 데이터를 정리합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;Server&lt;/span&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Data Scrubbing&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sentry 프로젝트 설정에서 저장 전 마스킹 규칙을 적용합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsInfoCard&quot;&gt;&lt;span&gt;Alert&lt;/span&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Allowlist&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Slack, Email, Webhook에는 필요한 최소 정보만 전달합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class=&quot;SENTRY_docsSubTitle&quot; data-ke-size=&quot;size23&quot;&gt;샘플링 전략&lt;/h3&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;모든 성능 데이터를 100% 수집하면 비용과 노이즈가 빠르게 증가할 수 있습니다. 일반적으로 에러 이벤트는 최대한 놓치지 않도록 유지하고, 성능 트랜잭션과 세션 리플레이는 낮은 비율부터 시작하는 것이 안전합니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsSampling&quot;&gt;
&lt;div&gt;&lt;span&gt;에러 이벤트&lt;/span&gt; &lt;b&gt;sampleRate: 1.0&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 초기에는 중요 장애를 놓치지 않도록 100% 수집 권장&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;성능 트레이스&lt;/span&gt; &lt;b&gt;tracesSampleRate: 0.05 ~ 0.1&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트래픽이 많은 서비스는 낮은 비율부터 시작&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;세션 리플레이&lt;/span&gt; &lt;b&gt;replaysOnErrorSampleRate: 1.0&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 세션은 낮게, 오류 발생 세션은 높게 설정&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionFaq&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;FAQ&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;9. 자주 묻는 질문&lt;/h2&gt;
&lt;div class=&quot;SENTRY_docsFaq&quot;&gt;&lt;details&gt;
&lt;summary&gt;Sentry는 로그 수집 도구와 무엇이 다른가요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 로그 수집 도구는 서버나 애플리케이션 로그를 저장하고 검색하는 데 강점이 있습니다. Sentry는 오류 이벤트를 코드 라인, 릴리스, 사용자 영향도, 성능 트랜잭션과 연결해 분석하는 데 강점이 있습니다.&lt;/p&gt;
&lt;/details&gt;&lt;details&gt;
&lt;summary&gt;운영 환경에서 tracesSampleRate를 1.0으로 설정해도 되나요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트래픽이 적은 내부 시스템이라면 가능하지만, 대규모 서비스에서는 비용과 노이즈가 빠르게 증가할 수 있습니다. 운영 환경에서는 0.05~0.1부터 시작하고, 핵심 기능만 tracesSampler로 높이는 방식을 권장합니다.&lt;/p&gt;
&lt;/details&gt;&lt;details&gt;
&lt;summary&gt;Source Map 파일은 서버에 배포해도 되나요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Source Map은 원본 코드 구조를 노출할 수 있으므로 public 경로에 그대로 두는 것은 권장하지 않습니다. Sentry에 업로드한 후 삭제하거나, 웹 서버에서 .map 파일 접근을 차단하는 방식이 안전합니다.&lt;/p&gt;
&lt;/details&gt;&lt;details&gt;
&lt;summary&gt;Session Replay는 개인정보 문제가 없나요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정에 따라 화면 텍스트, 입력값, 미디어가 포함될 수 있으므로 개인정보 보호 설정이 필수입니다. maskAllText, blockAllMedia, block, mask 옵션을 활용해 민감 영역을 반드시 보호해야 합니다.&lt;/p&gt;
&lt;/details&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionFinish&quot; class=&quot;SENTRY_docsSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;Conclusion&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;10. 마무리&lt;/h2&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;Sentry를 잘 도입하면 장애 대응 방식이 바뀝니다. 사용자가 오류를 제보한 뒤 로그를 뒤지는 방식에서, 어떤 사용자에게 어떤 화면에서 어떤 배포 이후 어떤 코드가 문제였는지 먼저 확인하고 대응하는 방식으로 전환할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;SENTRY_docsParagraph&quot; data-ke-size=&quot;size16&quot;&gt;다만 Sentry는 설치만으로 끝나는 도구가 아닙니다. 릴리스 관리, Source Map 자동화, 개인정보 제거, 샘플링 정책, 알림 라우팅, 담당자 지정까지 함께 설계해야 운영 환경에서 진짜 가치가 나옵니다.&lt;/p&gt;
&lt;div class=&quot;SENTRY_docsFinal&quot;&gt;&lt;b&gt;최종 정리&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sentry는 장애가 발생한 뒤 보는 로그 도구가 아니라, 장애가 사용자 경험에 미치는 영향을 코드와 배포 단위로 연결해주는 관측성 플랫폼입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;SENTRY_docsTags&quot;&gt;&lt;span&gt;Sentry&lt;/span&gt; &lt;span&gt;에러모니터링&lt;/span&gt; &lt;span&gt;성능모니터링&lt;/span&gt; &lt;span&gt;APM&lt;/span&gt; &lt;span&gt;Observability&lt;/span&gt; &lt;span&gt;프론트엔드&lt;/span&gt; &lt;span&gt;백엔드&lt;/span&gt; &lt;span&gt;React&lt;/span&gt; &lt;span&gt;ASP.NETCore&lt;/span&gt; &lt;span&gt;SourceMap&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;SENTRY_sectionReferences&quot; class=&quot;SENTRY_docsSection SENTRY_docsReferenceSection&quot;&gt;
&lt;div class=&quot;SENTRY_docsLabel&quot;&gt;References&lt;/div&gt;
&lt;h2 class=&quot;SENTRY_docsTitle&quot; data-ke-size=&quot;size26&quot;&gt;공식 문서 참고 링크&lt;/h2&gt;
&lt;ul class=&quot;SENTRY_docsReferenceList&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.sentry.io/platforms/javascript/configuration/options/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Sentry JavaScript SDK Options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.sentry.io/platforms/javascript/session-replay/configuration/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Sentry Session Replay Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.sentry.io/platforms/javascript/sourcemaps/uploading/vite/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Sentry Vite Source Map Upload&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/configuration/options/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Sentry ASP.NET Core Options&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/main&gt;&lt;/div&gt;
&lt;div&gt;
&lt;style&gt;
  #SENTRY_docsRoot,
  #SENTRY_docsRoot * {
    box-sizing: border-box !important;
  }

  #SENTRY_docsRoot {
    --SENTRY_primary: #5f4bb6;
    --SENTRY_primaryDark: #251d46;
    --SENTRY_primarySoft: #f3f0ff;
    --SENTRY_text: #111827;
    --SENTRY_muted: #5b6472;
    --SENTRY_border: #e3e7ef;
    --SENTRY_bg: #ffffff;
    --SENTRY_panel: #f8fafc;
    --SENTRY_codeBg: #0f172a;
    --SENTRY_codeHeader: #111827;
    --SENTRY_codeText: #e5e7eb;

    max-width: 1040px !important;
    margin: 0 auto !important;
    padding: 28px 16px 70px !important;
    color: var(--SENTRY_text) !important;
    font-family: &quot;Pretendard&quot;, &quot;Noto Sans KR&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif !important;
    line-height: 1.75 !important;
    word-break: keep-all !important;
    background: #ffffff !important;
    overflow-x: hidden !important;
  }

  #SENTRY_readProgress {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    z-index: 99999 !important;
    width: 0;
    height: 4px !important;
    background: linear-gradient(90deg, #5f4bb6, #8b7cf6, #38bdf8) !important;
  }

  .SENTRY_docsHero {
    overflow: hidden !important;
    position: relative !important;
    border-radius: 30px !important;
    background:
      radial-gradient(circle at 86% 12%, rgba(255,255,255,0.22), transparent 18%),
      radial-gradient(circle at 0% 100%, rgba(255,255,255,0.11), transparent 24%),
      linear-gradient(135deg, #21183e 0%, #382c66 48%, #6c5fc7 100%) !important;
    box-shadow: 0 30px 80px rgba(37, 29, 70, 0.30) !important;
  }

  .SENTRY_docsHeroGrid {
    display: grid !important;
    grid-template-columns: minmax(0, 1.45fr) minmax(300px, 0.75fr) !important;
    gap: 34px !important;
    align-items: center !important;
    padding: 58px 46px !important;
  }

  .SENTRY_docsHeroContent {
    position: relative !important;
    z-index: 2 !important;
    min-width: 0 !important;
  }

  .SENTRY_docsEyebrow {
    display: inline-flex !important;
    align-items: center !important;
    margin-bottom: 24px !important;
    padding: 8px 15px !important;
    border-radius: 999px !important;
    border: 1px solid rgba(255,255,255,0.35) !important;
    background: rgba(255,255,255,0.12) !important;
    color: #ffffff !important;
    font-size: 13px !important;
    font-weight: 900 !important;
    letter-spacing: 0.06em !important;
  }

  .SENTRY_docsHeroTitle {
    margin: 0 !important;
    max-width: 780px !important;
    color: #ffffff !important;
    font-size: clamp(34px, 5vw, 56px) !important;
    line-height: 1.14 !important;
    letter-spacing: -0.055em !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsHeroText {
    max-width: 820px !important;
    margin: 24px 0 0 !important;
    color: rgba(255,255,255,0.91) !important;
    font-size: 18px !important;
    line-height: 1.8 !important;
    font-weight: 500 !important;
  }

  .SENTRY_docsHeroMeta {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 14px !important;
    margin-top: 34px !important;
  }

  .SENTRY_docsHeroMeta div {
    min-height: 106px !important;
    padding: 19px !important;
    border-radius: 20px !important;
    border: 1px solid rgba(255,255,255,0.24) !important;
    background: rgba(255,255,255,0.12) !important;
    backdrop-filter: blur(10px) !important;
  }

  .SENTRY_docsHeroMeta span {
    display: block !important;
    margin-bottom: 9px !important;
    color: rgba(255,255,255,0.72) !important;
    font-size: 13px !important;
    font-weight: 800 !important;
  }

  .SENTRY_docsHeroMeta strong {
    display: block !important;
    color: #ffffff !important;
    font-size: 16px !important;
    line-height: 1.45 !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsThumbPanel {
    position: relative !important;
    z-index: 2 !important;
    min-width: 0 !important;
  }

  .SENTRY_docsThumbCard {
    position: relative !important;
    overflow: hidden !important;
    border-radius: 28px !important;
    border: 1px solid rgba(255,255,255,0.24) !important;
    background: rgba(255,255,255,0.12) !important;
    box-shadow: 0 30px 60px rgba(15, 23, 42, 0.26) !important;
    backdrop-filter: blur(12px) !important;
  }

  .SENTRY_docsThumbCard::before {
    content: &quot;&quot; !important;
    position: absolute !important;
    inset: 14px !important;
    border-radius: 22px !important;
    border: 1px solid rgba(255,255,255,0.16) !important;
    pointer-events: none !important;
  }

  .SENTRY_docsThumbTop {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    padding: 20px 22px 12px !important;
    color: #ffffff !important;
  }

  .SENTRY_docsThumbTop span {
    color: rgba(255,255,255,0.72) !important;
    font-size: 12px !important;
    font-weight: 800 !important;
    letter-spacing: 0.05em !important;
    text-transform: uppercase !important;
  }

  .SENTRY_docsThumbTop b {
    color: #ffffff !important;
    font-size: 18px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsThumbImage {
    margin: 0 auto !important;
    padding: 10px 28px 18px !important;
    text-align: center !important;
  }

  .SENTRY_docsThumbImage p {
    margin: 0 !important;
  }

  .SENTRY_docsThumbImage img,
  .SENTRY_docsThumbImage figure,
  .SENTRY_docsThumbImage .imageblock,
  .SENTRY_docsThumbImage .imageblock img {
    max-width: 100% !important;
    height: auto !important;
    margin: 0 auto !important;
    border-radius: 24px !important;
    display: block !important;
    box-shadow: 0 22px 45px rgba(0,0,0,0.24) !important;
  }

  .SENTRY_docsThumbBottom {
    padding: 0 22px 24px !important;
    text-align: left !important;
  }

  .SENTRY_docsThumbBottom strong {
    display: block !important;
    color: #ffffff !important;
    font-size: 22px !important;
    font-weight: 900 !important;
    line-height: 1.3 !important;
  }

  .SENTRY_docsThumbBottom span {
    display: block !important;
    margin-top: 6px !important;
    color: rgba(255,255,255,0.72) !important;
    font-size: 13px !important;
    line-height: 1.5 !important;
  }

  .SENTRY_docsMain {
    max-width: 860px !important;
    margin: 30px auto 0 !important;
    min-width: 0 !important;
  }

  .SENTRY_docsSection {
    margin-bottom: 26px !important;
    padding: 42px !important;
    border-radius: 28px !important;
    border: 1px solid var(--SENTRY_border) !important;
    background: #ffffff !important;
    box-shadow: 0 16px 46px rgba(15, 23, 42, 0.06) !important;
    overflow: hidden !important;
  }

  .SENTRY_docsLabel {
    display: inline-flex !important;
    margin-bottom: 14px !important;
    padding: 6px 12px !important;
    border-radius: 999px !important;
    background: var(--SENTRY_primarySoft) !important;
    color: var(--SENTRY_primary) !important;
    font-size: 12px !important;
    font-weight: 900 !important;
    letter-spacing: 0.08em !important;
    text-transform: uppercase !important;
  }

  .SENTRY_docsTitle {
    margin: 0 0 20px !important;
    padding-bottom: 14px !important;
    border-bottom: 1px solid var(--SENTRY_border) !important;
    color: #111827 !important;
    font-size: clamp(27px, 3vw, 38px) !important;
    line-height: 1.32 !important;
    letter-spacing: -0.045em !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsSubTitle {
    margin: 38px 0 14px !important;
    color: var(--SENTRY_primaryDark) !important;
    font-size: 23px !important;
    line-height: 1.42 !important;
    letter-spacing: -0.035em !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsParagraph {
    margin: 0 0 17px !important;
    color: #374151 !important;
    font-size: 16px !important;
    line-height: 1.95 !important;
  }

  .SENTRY_docsInfoGrid {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 16px !important;
    margin-top: 30px !important;
  }

  .SENTRY_docsInfoGridThree {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }

  .SENTRY_docsInfoCard {
    padding: 24px !important;
    border-radius: 24px !important;
    border: 1px solid #e7e3ff !important;
    background: linear-gradient(180deg, #ffffff 0%, #faf9ff 100%) !important;
    min-width: 0 !important;
  }

  .SENTRY_docsInfoCard span {
    display: inline-flex !important;
    margin-bottom: 14px !important;
    padding: 6px 10px !important;
    border-radius: 12px !important;
    background: var(--SENTRY_primary) !important;
    color: #ffffff !important;
    font-size: 12px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsInfoCard h3 {
    margin: 0 0 8px !important;
    color: #111827 !important;
    font-size: 20px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsInfoCard p {
    margin: 0 !important;
    color: var(--SENTRY_muted) !important;
    font-size: 14px !important;
    line-height: 1.75 !important;
  }

  .SENTRY_docsFlow {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 14px !important;
    margin: 30px 0 !important;
  }

  .SENTRY_docsFlow div {
    padding: 22px !important;
    border-radius: 22px !important;
    border: 1px solid var(--SENTRY_border) !important;
    background: var(--SENTRY_panel) !important;
    min-width: 0 !important;
  }

  .SENTRY_docsFlow strong {
    display: block !important;
    margin-bottom: 8px !important;
    color: var(--SENTRY_primaryDark) !important;
    font-size: 17px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsFlow p {
    margin: 0 !important;
    color: #4b5563 !important;
    font-size: 14px !important;
    line-height: 1.75 !important;
  }

  .SENTRY_docsCallout,
  .SENTRY_docsWarning,
  .SENTRY_docsFinal,
  .SENTRY_docsTip {
    margin-top: 24px !important;
    padding: 22px 24px !important;
    border-radius: 20px !important;
    border: 1px solid #d8d2ff !important;
    border-left: 6px solid var(--SENTRY_primary) !important;
    background: #fbfaff !important;
  }

  .SENTRY_docsTip {
    border-color: #bfdbfe !important;
    border-left-color: #2563eb !important;
    background: #eff6ff !important;
  }

  .SENTRY_docsWarning {
    border-color: #fed7aa !important;
    border-left-color: #f97316 !important;
    background: #fff7ed !important;
  }

  .SENTRY_docsFinal {
    border-color: #bbf7d0 !important;
    border-left-color: #16a34a !important;
    background: #f0fdf4 !important;
  }

  .SENTRY_docsCallout strong,
  .SENTRY_docsWarning strong,
  .SENTRY_docsFinal strong,
  .SENTRY_docsTip strong {
    display: block !important;
    margin-bottom: 8px !important;
    color: #111827 !important;
    font-size: 17px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsCallout p,
  .SENTRY_docsWarning p,
  .SENTRY_docsFinal p,
  .SENTRY_docsTip p {
    margin: 0 !important;
    color: #374151 !important;
    font-size: 15px !important;
    line-height: 1.8 !important;
  }

  .SENTRY_codeBox {
    overflow: hidden !important;
    margin: 26px 0 34px !important;
    border-radius: 20px !important;
    border: 1px solid #1f2937 !important;
    background: var(--SENTRY_codeBg) !important;
    box-shadow: 0 18px 42px rgba(15, 23, 42, 0.22) !important;
  }

  .SENTRY_codeHeader {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    gap: 12px !important;
    padding: 14px 18px !important;
    background: var(--SENTRY_codeHeader) !important;
    border-bottom: 1px solid rgba(255,255,255,0.08) !important;
  }

  .SENTRY_codeHeader span {
    color: #f9fafb !important;
    font-size: 14px !important;
    font-weight: 900 !important;
  }

  .SENTRY_codeHeader button {
    min-width: 62px !important;
    padding: 7px 13px !important;
    border-radius: 999px !important;
    border: 1px solid rgba(196,181,253,0.6) !important;
    background: rgba(139, 92, 246, 0.18) !important;
    color: #ddd6fe !important;
    font-size: 12px !important;
    font-weight: 900 !important;
    cursor: pointer !important;
  }

  .SENTRY_codeHeader button:hover {
    background: #7c3aed !important;
    color: #ffffff !important;
  }

  .SENTRY_codeBox pre {
    margin: 0 !important;
    padding: 24px !important;
    overflow-x: auto !important;
    background: var(--SENTRY_codeBg) !important;
    color: var(--SENTRY_codeText) !important;
    font-size: 14px !important;
    line-height: 1.75 !important;
    tab-size: 2 !important;
    white-space: pre !important;
  }

  .SENTRY_codeBox code {
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    color: #e5e7eb !important;
    font-family: &quot;D2Coding&quot;, &quot;Fira Code&quot;, Consolas, Monaco, monospace !important;
    font-size: 14px !important;
    line-height: 1.75 !important;
    text-shadow: none !important;
  }

  .SENTRY_docsTableWrap {
    overflow-x: auto !important;
    margin-top: 24px !important;
    border-radius: 18px !important;
    border: 1px solid var(--SENTRY_border) !important;
  }

  .SENTRY_docsTable {
    width: 100% !important;
    min-width: 720px !important;
    border-collapse: collapse !important;
    background: #ffffff !important;
  }

  .SENTRY_docsTable th {
    padding: 16px !important;
    background: var(--SENTRY_primaryDark) !important;
    color: #ffffff !important;
    font-size: 14px !important;
    text-align: left !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsTable td {
    padding: 16px !important;
    border-top: 1px solid var(--SENTRY_border) !important;
    color: #374151 !important;
    font-size: 14px !important;
    line-height: 1.7 !important;
    vertical-align: top !important;
  }

  .SENTRY_docsTable code {
    display: inline-flex !important;
    align-items: center !important;
    padding: 2px 7px !important;
    border-radius: 7px !important;
    background: #f3f4f6 !important;
    color: #4c1d95 !important;
    font-family: &quot;D2Coding&quot;, &quot;Fira Code&quot;, Consolas, Monaco, monospace !important;
    font-size: 13px !important;
    font-weight: 800 !important;
    white-space: nowrap !important;
  }

  .SENTRY_docsChecklist {
    margin-top: 24px !important;
    padding: 24px !important;
    border-radius: 20px !important;
    border: 1px solid var(--SENTRY_border) !important;
    background: var(--SENTRY_panel) !important;
  }

  .SENTRY_docsChecklist h3 {
    margin: 0 0 12px !important;
    color: #111827 !important;
    font-size: 19px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsChecklist ul,
  .SENTRY_docsReferenceList {
    margin: 0 !important;
    padding-left: 22px !important;
  }

  .SENTRY_docsChecklist li,
  .SENTRY_docsReferenceList li {
    margin: 8px 0 !important;
    color: #374151 !important;
    font-size: 15px !important;
    line-height: 1.7 !important;
  }

  .SENTRY_docsReferenceList a {
    color: var(--SENTRY_primary) !important;
    font-weight: 900 !important;
    text-decoration: none !important;
  }

  .SENTRY_docsReferenceList a:hover {
    text-decoration: underline !important;
  }

  .SENTRY_docsSampling {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 14px !important;
    margin-top: 22px !important;
  }

  .SENTRY_docsSampling div {
    padding: 22px !important;
    border-radius: 20px !important;
    border: 1px solid var(--SENTRY_border) !important;
    background: #ffffff !important;
    box-shadow: 0 10px 28px rgba(15,23,42,0.05) !important;
    min-width: 0 !important;
  }

  .SENTRY_docsSampling span {
    display: inline-flex !important;
    margin-bottom: 10px !important;
    padding: 5px 10px !important;
    border-radius: 999px !important;
    background: var(--SENTRY_primarySoft) !important;
    color: var(--SENTRY_primary) !important;
    font-size: 12px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsSampling strong {
    display: block !important;
    margin-bottom: 8px !important;
    color: var(--SENTRY_primaryDark) !important;
    font-size: 17px !important;
    font-weight: 900 !important;
  }

  .SENTRY_docsSampling p {
    margin: 0 !important;
    color: #4b5563 !important;
    font-size: 14px !important;
    line-height: 1.7 !important;
  }

  .SENTRY_docsFaq {
    display: grid !important;
    gap: 12px !important;
    margin-top: 24px !important;
  }

  .SENTRY_docsFaq details {
    border: 1px solid var(--SENTRY_border) !important;
    border-radius: 18px !important;
    background: #ffffff !important;
    overflow: hidden !important;
  }

  .SENTRY_docsFaq summary {
    cursor: pointer !important;
    padding: 18px 20px !important;
    color: #111827 !important;
    font-size: 16px !important;
    font-weight: 900 !important;
    background: #f8fafc !important;
  }

  .SENTRY_docsFaq p {
    margin: 0 !important;
    padding: 18px 20px !important;
    color: #374151 !important;
    font-size: 15px !important;
    line-height: 1.8 !important;
  }

  .SENTRY_docsTags {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 9px !important;
    margin-top: 28px !important;
  }

  .SENTRY_docsTags span {
    display: inline-flex !important;
    padding: 8px 13px !important;
    border-radius: 999px !important;
    background: var(--SENTRY_primarySoft) !important;
    color: var(--SENTRY_primary) !important;
    font-size: 13px !important;
    font-weight: 900 !important;
  }

  @media (max-width: 900px) {
    .SENTRY_docsHeroGrid {
      grid-template-columns: 1fr !important;
    }

    .SENTRY_docsThumbPanel {
      max-width: 420px !important;
      margin: 0 auto !important;
      width: 100% !important;
    }

    .SENTRY_docsHeroMeta,
    .SENTRY_docsInfoGrid,
    .SENTRY_docsInfoGridThree,
    .SENTRY_docsFlow,
    .SENTRY_docsSampling {
      grid-template-columns: 1fr !important;
    }
  }

  @media (max-width: 560px) {
    #SENTRY_docsRoot {
      padding: 16px 10px 50px !important;
    }

    .SENTRY_docsHeroGrid {
      padding: 40px 22px !important;
    }

    .SENTRY_docsHeroTitle {
      font-size: 32px !important;
    }

    .SENTRY_docsHeroText {
      font-size: 15px !important;
    }

    .SENTRY_docsMain {
      margin-top: 22px !important;
    }

    .SENTRY_docsSection {
      padding: 26px 18px !important;
      border-radius: 22px !important;
    }

    .SENTRY_docsParagraph {
      font-size: 15px !important;
    }

    .SENTRY_codeBox pre,
    .SENTRY_codeBox code {
      font-size: 13px !important;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  function SENTRY_copyCode(SENTRY_codeId) {
    var SENTRY_codeElement = document.getElementById(SENTRY_codeId);

    if (!SENTRY_codeElement) {
      alert(&quot;복사할 코드 영역을 찾지 못했습니다.&quot;);
      return;
    }

    var SENTRY_codeText = SENTRY_codeElement.innerText;

    if (navigator.clipboard &amp;&amp; window.isSecureContext) {
      navigator.clipboard.writeText(SENTRY_codeText)
        .then(function () {
          SENTRY_showCopySuccess(SENTRY_codeId);
        })
        .catch(function () {
          SENTRY_fallbackCopy(SENTRY_codeText, SENTRY_codeId);
        });
    } else {
      SENTRY_fallbackCopy(SENTRY_codeText, SENTRY_codeId);
    }
  }

  function SENTRY_fallbackCopy(SENTRY_codeText, SENTRY_codeId) {
    var SENTRY_textarea = document.createElement(&quot;textarea&quot;);

    SENTRY_textarea.value = SENTRY_codeText;
    SENTRY_textarea.setAttribute(&quot;readonly&quot;, &quot;&quot;);
    SENTRY_textarea.style.position = &quot;fixed&quot;;
    SENTRY_textarea.style.top = &quot;-9999px&quot;;
    SENTRY_textarea.style.left = &quot;-9999px&quot;;

    document.body.appendChild(SENTRY_textarea);
    SENTRY_textarea.select();

    try {
      document.execCommand(&quot;copy&quot;);
      SENTRY_showCopySuccess(SENTRY_codeId);
    } catch (SENTRY_error) {
      alert(&quot;브라우저 정책으로 인해 복사에 실패했습니다.&quot;);
    }

    document.body.removeChild(SENTRY_textarea);
  }

  function SENTRY_showCopySuccess(SENTRY_codeId) {
    var SENTRY_buttons = document.querySelectorAll(&quot;.SENTRY_codeHeader button&quot;);

    SENTRY_buttons.forEach(function (SENTRY_button) {
      var SENTRY_onclickValue = SENTRY_button.getAttribute(&quot;onclick&quot;) || &quot;&quot;;

      if (SENTRY_onclickValue.indexOf(SENTRY_codeId) !== -1) {
        var SENTRY_originalText = SENTRY_button.innerText;

        SENTRY_button.innerText = &quot;완료&quot;;
        SENTRY_button.style.background = &quot;#16a34a&quot;;
        SENTRY_button.style.borderColor = &quot;#16a34a&quot;;
        SENTRY_button.style.color = &quot;#ffffff&quot;;

        setTimeout(function () {
          SENTRY_button.innerText = SENTRY_originalText;
          SENTRY_button.style.background = &quot;rgba(139, 92, 246, 0.18)&quot;;
          SENTRY_button.style.borderColor = &quot;rgba(196,181,253,0.6)&quot;;
          SENTRY_button.style.color = &quot;#ddd6fe&quot;;
        }, 1600);
      }
    });
  }

  function SENTRY_updateReadProgress() {
    var SENTRY_progress = document.getElementById(&quot;SENTRY_readProgress&quot;);

    if (!SENTRY_progress) {
      return;
    }

    var SENTRY_scrollTop = window.scrollY || document.documentElement.scrollTop;
    var SENTRY_docHeight = document.documentElement.scrollHeight - window.innerHeight;
    var SENTRY_progressRate = SENTRY_docHeight &gt; 0 ? (SENTRY_scrollTop / SENTRY_docHeight) * 100 : 0;

    SENTRY_progress.style.width = SENTRY_progressRate + &quot;%&quot;;
  }

  document.addEventListener(&quot;scroll&quot;, SENTRY_updateReadProgress);
  document.addEventListener(&quot;DOMContentLoaded&quot;, SENTRY_updateReadProgress);
&lt;/script&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{
  &quot;@context&quot;: &quot;https://schema.org&quot;,
  &quot;@type&quot;: &quot;TechArticle&quot;,
  &quot;headline&quot;: &quot;Sentry 완벽 가이드: 에러 추적부터 성능 모니터링까지&quot;,
  &quot;description&quot;: &quot;React, ASP.NET Core, API 서버 환경에서 Sentry를 활용해 에러 모니터링, 성능 트레이싱, Source Map, Session Replay, 샘플링 전략을 정리한 실무 가이드입니다.&quot;,
  &quot;keywords&quot;: [
    &quot;Sentry&quot;,
    &quot;에러모니터링&quot;,
    &quot;성능모니터링&quot;,
    &quot;APM&quot;,
    &quot;Observability&quot;,
    &quot;React&quot;,
    &quot;ASP.NET Core&quot;,
    &quot;Source Map&quot;,
    &quot;Session Replay&quot;,
    &quot;분산 트레이싱&quot;
  ],
  &quot;inLanguage&quot;: &quot;ko-KR&quot;,
  &quot;author&quot;: {
    &quot;@type&quot;: &quot;Person&quot;,
    &quot;name&quot;: &quot;OdinBOX&quot;
  },
  &quot;publisher&quot;: {
    &quot;@type&quot;: &quot;Organization&quot;,
    &quot;name&quot;: &quot;OdinBOX&quot;
  }
}
&lt;/script&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{
  &quot;@context&quot;: &quot;https://schema.org&quot;,
  &quot;@type&quot;: &quot;FAQPage&quot;,
  &quot;mainEntity&quot;: [
    {
      &quot;@type&quot;: &quot;Question&quot;,
      &quot;name&quot;: &quot;Sentry는 로그 수집 도구와 무엇이 다른가요?&quot;,
      &quot;acceptedAnswer&quot;: {
        &quot;@type&quot;: &quot;Answer&quot;,
        &quot;text&quot;: &quot;일반 로그 수집 도구는 서버나 애플리케이션 로그를 저장하고 검색하는 데 강점이 있습니다. Sentry는 오류 이벤트를 코드 라인, 릴리스, 사용자 영향도, 성능 트랜잭션과 연결해 분석하는 데 강점이 있습니다.&quot;
      }
    },
    {
      &quot;@type&quot;: &quot;Question&quot;,
      &quot;name&quot;: &quot;운영 환경에서 tracesSampleRate를 1.0으로 설정해도 되나요?&quot;,
      &quot;acceptedAnswer&quot;: {
        &quot;@type&quot;: &quot;Answer&quot;,
        &quot;text&quot;: &quot;트래픽이 적은 내부 시스템이라면 가능하지만, 대규모 서비스에서는 비용과 노이즈가 빠르게 증가할 수 있습니다. 운영 환경에서는 0.05~0.1부터 시작하고, 핵심 기능만 tracesSampler로 높이는 방식을 권장합니다.&quot;
      }
    },
    {
      &quot;@type&quot;: &quot;Question&quot;,
      &quot;name&quot;: &quot;Source Map 파일은 서버에 배포해도 되나요?&quot;,
      &quot;acceptedAnswer&quot;: {
        &quot;@type&quot;: &quot;Answer&quot;,
        &quot;text&quot;: &quot;Source Map은 원본 코드 구조를 노출할 수 있으므로 public 경로에 그대로 두는 것은 권장하지 않습니다. Sentry에 업로드한 후 삭제하거나, 웹 서버에서 .map 파일 접근을 차단하는 방식이 안전합니다.&quot;
      }
    },
    {
      &quot;@type&quot;: &quot;Question&quot;,
      &quot;name&quot;: &quot;Session Replay는 개인정보 문제가 없나요?&quot;,
      &quot;acceptedAnswer&quot;: {
        &quot;@type&quot;: &quot;Answer&quot;,
        &quot;text&quot;: &quot;설정에 따라 화면 텍스트, 입력값, 미디어가 포함될 수 있으므로 개인정보 보호 설정이 필수입니다. maskAllText, blockAllMedia, block, mask 옵션을 활용해 민감 영역을 반드시 보호해야 합니다.&quot;
      }
    }
  ]
}
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>APM</category>
      <category>asp.netcore</category>
      <category>Observability</category>
      <category>React</category>
      <category>Sentry</category>
      <category>SourceMAP</category>
      <category>백엔드</category>
      <category>성능모니터링</category>
      <category>에러모니터링</category>
      <category>프론트엔드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/582</guid>
      <comments>https://odinbox.tistory.com/582#entry582comment</comments>
      <pubDate>Sun, 26 Apr 2026 20:01:02 +0900</pubDate>
    </item>
    <item>
      <title>웹 서비스 API 문서화의 표준 [Swagger와 OpenAPI]</title>
      <link>https://odinbox.tistory.com/581</link>
      <description>&lt;div&gt;
&lt;style&gt;
  :root {
    --wsinfo_bg: #f5f7fb;
    --wsinfo_surface: #ffffff;
    --wsinfo_surface_soft: #f8fbff;
    --wsinfo_text: #1a2330;
    --wsinfo_text_soft: #586577;
    --wsinfo_line: #dde6f0;
    --wsinfo_line_strong: #c8d5e4;
    --wsinfo_primary: #173b73;
    --wsinfo_primary_soft: #eef4ff;
    --wsinfo_secondary: #0f766e;
    --wsinfo_warn_bg: #fff8e8;
    --wsinfo_warn_line: #efd38c;
    --wsinfo_shadow: 0 18px 40px rgba(15, 23, 42, 0.08);
    --wsinfo_radius_xl: 28px;
    --wsinfo_radius_lg: 22px;
    --wsinfo_radius_md: 16px;
    --wsinfo_maxw: 980px;
  }

  .wsinfo_wrap,
  .wsinfo_wrap * {
    box-sizing: border-box;
  }

  .wsinfo_wrap {
    max-width: var(--wsinfo_maxw);
    margin: 0 auto;
    padding: 8px 0 42px;
    color: var(--wsinfo_text);
    font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Apple SD Gothic Neo&quot;, &quot;Noto Sans KR&quot;, &quot;Malgun Gothic&quot;, sans-serif;
    line-height: 1.82;
    word-break: keep-all;
  }

  .wsinfo_wrap img {
    max-width: 100%;
    height: auto;
    border: 0;
  }

  .wsinfo_wrap a {
    color: var(--wsinfo_primary);
    text-decoration: none;
    border-bottom: 1px solid rgba(23, 59, 115, 0.18);
  }

  .wsinfo_hero {
    position: relative;
    overflow: hidden;
    padding: 24px 26px 30px;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_xl);
    background:
      radial-gradient(circle at top right, rgba(23, 59, 115, 0.12), transparent 30%),
      linear-gradient(135deg, #ffffff 0%, #f7faff 58%, #eef4fb 100%);
    box-shadow: var(--wsinfo_shadow);
  }

  .wsinfo_thumb {
    margin: 0 0 18px;
    padding: 0;
    text-align: center;
  }

  .wsinfo_eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 14px;
    padding: 7px 12px;
    border: 1px solid #cfdaea;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.88);
    color: var(--wsinfo_primary);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .wsinfo_title {
    margin: 0;
    font-size: 35px;
    line-height: 1.28;
    letter-spacing: -0.03em;
    color: #0f1b2d;
  }

  .wsinfo_lead {
    margin: 16px 0 0;
    font-size: 17px;
    color: var(--wsinfo_text_soft);
  }

  .wsinfo_meta {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
  }

  .wsinfo_meta_item {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 8px 12px;
    border: 1px solid var(--wsinfo_line);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.84);
    color: var(--wsinfo_text_soft);
    font-size: 13px;
    font-weight: 700;
  }

  .wsinfo_notice {
    margin-top: 16px;
    padding: 14px 16px;
    border: 1px solid var(--wsinfo_warn_line);
    border-radius: var(--wsinfo_radius_md);
    background: var(--wsinfo_warn_bg);
    color: #6b5618;
    font-size: 14px;
  }

  .wsinfo_section {
    margin-top: 28px;
    padding: 28px 26px;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_lg);
    background: var(--wsinfo_surface);
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.04);
  }

  .wsinfo_section_title {
    margin: 0 0 16px;
    font-size: 28px;
    line-height: 1.35;
    letter-spacing: -0.025em;
    color: #11223a;
  }

  .wsinfo_section_subtitle {
    margin: 0 0 16px;
    color: var(--wsinfo_text_soft);
    font-size: 15px;
  }

  .wsinfo_section p {
    margin: 0 0 14px;
    font-size: 16px;
  }

  .wsinfo_section p:last-child,
  .wsinfo_cards_item p:last-child,
  .wsinfo_steps_item p:last-child,
  .wsinfo_list li:last-child,
  .wsinfo_checklist li:last-child,
  .wsinfo_timeline_item p:last-child,
  .wsinfo_matrix_item p:last-child {
    margin-bottom: 0;
  }

  .wsinfo_point {
    color: var(--wsinfo_primary);
    font-weight: 800;
  }

  .wsinfo_divider {
    height: 1px;
    margin: 24px 0;
    background: linear-gradient(to right, transparent, #d8e3ef, transparent);
  }

  .wsinfo_grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-top: 18px;
  }

  .wsinfo_cards_item {
    padding: 18px 18px 16px;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_md);
    background: var(--wsinfo_surface_soft);
  }

  .wsinfo_cards_kicker {
    margin: 0 0 8px;
    color: var(--wsinfo_primary);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .wsinfo_cards_title {
    margin: 0 0 8px;
    font-size: 19px;
    line-height: 1.45;
    color: #12253f;
  }

  .wsinfo_cards_item p {
    margin: 0 0 10px;
    color: var(--wsinfo_text_soft);
    font-size: 15px;
  }

  .wsinfo_quote {
    margin-top: 18px;
    padding: 18px 20px;
    border-left: 4px solid var(--wsinfo_primary);
    border-radius: 0 var(--wsinfo_radius_md) var(--wsinfo_radius_md) 0;
    background: #f3f7fe;
  }

  .wsinfo_quote p {
    margin: 0;
    font-size: 16px;
    color: #1d304c;
  }

  .wsinfo_timeline {
    position: relative;
    margin: 18px 0 0;
    padding: 0;
    list-style: none;
  }

  .wsinfo_timeline::before {
    content: &quot;&quot;;
    position: absolute;
    top: 8px;
    bottom: 8px;
    left: 15px;
    width: 2px;
    background: linear-gradient(to bottom, #b8cade, #dce7f2);
  }

  .wsinfo_timeline_item {
    position: relative;
    margin: 0 0 16px;
    padding-left: 46px;
  }

  .wsinfo_timeline_item:last-child {
    margin-bottom: 0;
  }

  .wsinfo_timeline_item::before {
    content: &quot;&quot;;
    position: absolute;
    top: 8px;
    left: 8px;
    width: 16px;
    height: 16px;
    border: 3px solid #ffffff;
    border-radius: 50%;
    background: var(--wsinfo_primary);
    box-shadow: 0 0 0 1px #c0d1e2;
  }

  .wsinfo_timeline_badge {
    display: inline-block;
    margin-bottom: 4px;
    color: var(--wsinfo_primary);
    font-size: 13px;
    font-weight: 800;
  }

  .wsinfo_timeline_item p {
    margin: 0;
    font-size: 15px;
    color: var(--wsinfo_text_soft);
  }

  .wsinfo_steps {
    display: grid;
    gap: 14px;
    margin-top: 18px;
  }

  .wsinfo_steps_item {
    display: grid;
    grid-template-columns: 58px 1fr;
    gap: 14px;
    align-items: start;
    padding: 16px;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_md);
    background: #ffffff;
  }

  .wsinfo_steps_no {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 58px;
    height: 58px;
    border-radius: 18px;
    background: var(--wsinfo_primary_soft);
    color: var(--wsinfo_primary);
    font-size: 20px;
    font-weight: 900;
  }

  .wsinfo_steps_title {
    margin: 2px 0 6px;
    font-size: 18px;
    color: #132743;
  }

  .wsinfo_steps_item p {
    margin: 0;
    font-size: 15px;
    color: var(--wsinfo_text_soft);
  }

  .wsinfo_list,
  .wsinfo_checklist {
    margin: 16px 0 0;
    padding: 0;
    list-style: none;
  }

  .wsinfo_list li,
  .wsinfo_checklist li {
    position: relative;
    margin: 0 0 12px;
    padding-left: 18px;
    color: var(--wsinfo_text_soft);
    font-size: 15px;
  }

  .wsinfo_list li::before {
    content: &quot;&quot;;
    position: absolute;
    top: 12px;
    left: 0;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--wsinfo_primary);
  }

  .wsinfo_checklist li::before {
    content: &quot;✓&quot;;
    position: absolute;
    top: 0;
    left: 0;
    color: var(--wsinfo_secondary);
    font-weight: 900;
  }

  .wsinfo_matrix {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    margin-top: 18px;
  }

  .wsinfo_matrix_item {
    padding: 18px;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_md);
    background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%);
  }

  .wsinfo_matrix_item h4 {
    margin: 0 0 10px;
    font-size: 18px;
    line-height: 1.4;
    color: #132743;
  }

  .wsinfo_matrix_item p {
    margin: 0;
    color: var(--wsinfo_text_soft);
    font-size: 15px;
  }

  .wsinfo_table_wrap {
    margin-top: 18px;
    overflow-x: auto;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_md);
    background: #ffffff;
  }

  .wsinfo_table {
    width: 100%;
    min-width: 720px;
    border-collapse: collapse;
  }

  .wsinfo_table th,
  .wsinfo_table td {
    padding: 14px 14px;
    border-bottom: 1px solid var(--wsinfo_line);
    vertical-align: top;
    text-align: left;
    font-size: 14px;
    line-height: 1.7;
  }

  .wsinfo_table th {
    background: #f4f8fd;
    color: #15335f;
    font-weight: 800;
  }

  .wsinfo_table tr:last-child td {
    border-bottom: 0;
  }

  .wsinfo_footer {
    margin-top: 24px;
    padding: 18px 20px;
    border: 1px solid var(--wsinfo_line);
    border-radius: var(--wsinfo_radius_lg);
    background: #f7fbff;
    color: var(--wsinfo_text_soft);
    font-size: 14px;
  }

  @media (max-width: 860px) {
    .wsinfo_title {
      font-size: 28px;
    }

    .wsinfo_grid,
    .wsinfo_matrix {
      grid-template-columns: 1fr;
    }
  }

  @media (max-width: 560px) {
    .wsinfo_wrap {
      padding: 0 0 30px;
    }

    .wsinfo_hero,
    .wsinfo_section,
    .wsinfo_footer {
      padding-left: 18px;
      padding-right: 18px;
    }

    .wsinfo_title {
      font-size: 24px;
    }

    .wsinfo_lead,
    .wsinfo_section p {
      font-size: 15px;
    }

    .wsinfo_steps_item {
      grid-template-columns: 1fr;
    }

    .wsinfo_steps_no {
      width: 48px;
      height: 48px;
      border-radius: 14px;
      font-size: 18px;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_wrap&quot;&gt;
&lt;section class=&quot;wsinfo_hero&quot;&gt;
&lt;div class=&quot;wsinfo_thumb&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rev11/dJMcagSKyWx/0kpokS7n0UpXKrjiVqqrB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rev11/dJMcagSKyWx/0kpokS7n0UpXKrjiVqqrB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rev11/dJMcagSKyWx/0kpokS7n0UpXKrjiVqqrB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRev11%2FdJMcagSKyWx%2F0kpokS7n0UpXKrjiVqqrB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_eyebrow&quot;&gt;Web Service Documentation Strategy&lt;/div&gt;
&lt;p class=&quot;wsinfo_lead&quot; data-ke-size=&quot;size16&quot;&gt;API는 이제 단순한 데이터 전달 통로가 아닙니다. 프론트엔드와 백엔드, 내부 시스템과 외부 고객사, 운영 환경과 개발 생태계를 하나로 연결하는 핵심 계약입니다. 그래서 API 문서는 부가 자료가 아니라 &lt;span class=&quot;wsinfo_point&quot;&gt;서비스 품질과 협업 수준을 드러내는 기술 자산&lt;/span&gt;이 되어야 합니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_notice&quot;&gt;수동 문서화는 빠르게 낡습니다. 실무에서는 코드와 문서가 함께 움직이는 살아있는 문서 체계가 필요합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;왜 지금 Swagger와 OpenAPI를 다시 봐야 하는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대의 웹 서비스는 단일 애플리케이션 중심에서 벗어나 다수의 서비스가 연결되는 구조로 빠르게 이동했습니다. 마이크로서비스, 외부 연동, 고객사 API 제공, 모바일 앱, 관리자 시스템, 파트너 시스템이 동시에 연결되면서 &lt;span class=&quot;wsinfo_point&quot;&gt;정확한 인터페이스 정의와 신뢰 가능한 문서&lt;/span&gt;가 없으면 개발 속도보다 장애 속도가 더 빨라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거에는 워드, 위키, 엑셀 같은 수동 방식으로 API 명세를 관리하는 경우가 많았습니다. 하지만 이 방식은 코드 변경과 문서 갱신이 분리되어 결국 죽은 문서를 양산합니다. 프론트엔드 개발자와 외부 고객사는 오래된 문서를 보고 연동하다가 오류를 만나고, 내부 개발팀은 소스와 문서를 오가며 불필요한 맥락 전환 비용을 치르게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 이 지점을 해결하기 위해 등장한 것이 &lt;span class=&quot;wsinfo_point&quot;&gt;OpenAPI 사양과 Swagger 생태계&lt;/span&gt;입니다. 기계와 사람이 모두 읽을 수 있는 문서를 기준으로, 문서화&amp;middot;테스트&amp;middot;모킹&amp;middot;코드 생성&amp;middot;배포 자동화까지 연결하는 방식입니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_quote&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 API 문서는 개발 결과를 설명하는 부속물이 아니라, 개발과 운영 전체를 움직이는 기준점입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;Swagger와 OpenAPI는 무엇이 다를까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현업에서는 두 용어를 자주 섞어 쓰지만, 정확히 구분하면 설계와 운영 수준이 달라집니다. &lt;span class=&quot;wsinfo_point&quot;&gt;OpenAPI는 API를 기술하는 표준 사양&lt;/span&gt;이고, &lt;span class=&quot;wsinfo_point&quot;&gt;Swagger는 그 사양을 시각화하고 활용하는 도구 모음&lt;/span&gt;에 가깝습니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_grid&quot;&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;OpenAPI Specification&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;API를 정의하는 공식 계약 문서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;YAML 또는 JSON 포맷으로 작성되며, 엔드포인트, 요청 본문, 응답 스키마, 인증 방식, 서버 정보, 버전 같은 요소를 표준 형식으로 기술합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;Swagger Tooling&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;문서를 보여주고 테스트하고 생성하는 실행 도구&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swagger UI, Swagger Editor, Codegen 같은 도구들이 여기에 포함됩니다. 즉, 문서의 형식이 OpenAPI라면 그것을 실제 개발 경험으로 연결해 주는 계층이 Swagger입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_divider&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAPI 문서의 구조는 생각보다 명확합니다. &lt;b&gt;openapi&lt;/b&gt;로 사양 버전을 명시하고, &lt;b&gt;info&lt;/b&gt;에 서비스 정보를 넣고, &lt;b&gt;servers&lt;/b&gt;에 환경별 베이스 URL을 정의하며, &lt;b&gt;paths&lt;/b&gt;에서 실제 API 경로와 메서드를 설명합니다. 그리고 &lt;b&gt;components&lt;/b&gt;에서 공통 스키마와 인증 정의를 재사용하는 구조로 설계됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 특히 중요한 부분은 components와 $ref입니다. 요청/응답 모델을 매번 반복 작성하지 않고 재사용할 수 있기 때문에, 대규모 프로젝트일수록 문서 품질과 유지보수성이 눈에 띄게 좋아집니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;Node.js와 Express에서 Swagger를 적용하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js 기반 Express 프로젝트에서는 런타임에 주석을 파싱해 명세를 만드는 방식이 일반적입니다. 실무에서 가장 많이 쓰는 조합은 &lt;span class=&quot;wsinfo_point&quot;&gt;swagger-jsdoc + swagger-ui-express&lt;/span&gt;입니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_steps&quot;&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;01&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;swagger-jsdoc으로 명세 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSDoc 주석에 작성한 OpenAPI 정보를 읽어 JSON 스펙 객체로 변환합니다. openapi, info, servers, apis 경로를 설정해 문서의 뼈대를 만듭니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;02&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;swagger-ui-express로 UI 바인딩&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 스펙을 /api-docs 같은 경로에 연결해 브라우저에서 시각적으로 확인할 수 있게 합니다. 테스트까지 가능한 인터랙티브 문서가 즉시 구성됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;03&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;라우트별 주석으로 상세 명세 작성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 API 핸들러 상단에 @openapi 또는 @swagger 블록을 작성해 summary, tags, parameters, requestBody, responses를 기술합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;04&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;복잡한 모델은 components로 분리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통 응답 구조, 에러 포맷, 페이징 모델, 인증 스키마는 components에 두고 $ref로 참조하면 문서가 훨씬 읽기 쉬워지고 중복 관리도 줄어듭니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul class=&quot;wsinfo_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Node.js 쪽은 유연하고 빠르지만, 주석 규칙이 흐트러지면 문서 일관성이 무너지기 쉽습니다.&lt;/li&gt;
&lt;li&gt;프로젝트 초기에 tags 규칙, 응답 포맷 규칙, 에러 포맷 규칙을 먼저 통일하는 것이 좋습니다.&lt;/li&gt;
&lt;li&gt;문서 경로와 소스 경로 분리는 배포 전에 꼭 점검해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;Spring Boot 3에서는 무엇이 핵심인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Boot 진영에서는 예전의 Springfox보다 &lt;span class=&quot;wsinfo_point&quot;&gt;springdoc-openapi&lt;/span&gt;가 사실상 표준입니다. 특히 Spring Boot 3부터는 jakarta 전환 이슈 때문에 호환성 관점에서도 springdoc-openapi 쪽이 훨씬 안정적입니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_grid&quot;&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;Starter&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;의존성 추가만으로 기본 구조 활성화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;springdoc-openapi-starter-webmvc-ui 의존성을 추가하면 별도의 복잡한 설정 없이 OpenAPI JSON과 Swagger UI 엔드포인트를 빠르게 열 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;Annotation&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;어노테이션 기반 명세 고도화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Tag, @Operation, @Schema, @SecurityRequirement 등을 활용하면 컨트롤러와 DTO 레벨에서 풍부한 설명과 예시를 체계적으로 문서화할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_divider&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 품질을 가르는 지점은 자동 생성 자체가 아닙니다. &lt;span class=&quot;wsinfo_point&quot;&gt;도메인 단위 그룹화, DTO 예시 데이터, 인증 요구사항, 응답 표준화&lt;/span&gt;가 얼마나 잘 정리됐는지가 중요합니다. 같은 Swagger라도 여기가 정리돼 있으면 고객사가 바로 이해할 수 있고, 정리돼 있지 않으면 내부 팀도 다시 물어보게 됩니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;.NET과 ASP.NET Core에서는 어떻게 접근해야 하나&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 서비스 문서화를 닷넷 관점에서 보면 버전 구분이 꽤 중요합니다. 예전에는 &lt;span class=&quot;wsinfo_point&quot;&gt;Swashbuckle.AspNetCore&lt;/span&gt;가 사실상 기본 선택지처럼 쓰였지만, 최신 ASP.NET Core에서는 &lt;span class=&quot;wsinfo_point&quot;&gt;기본 제공 OpenAPI 지원&lt;/span&gt;을 중심으로 보는 편이 더 자연스럽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 실무에서는 &amp;ldquo;Swagger를 붙였다&amp;rdquo;보다 &lt;span class=&quot;wsinfo_point&quot;&gt;문서 생성 계층과 UI 계층을 분리해서 이해하는 것&lt;/span&gt;이 중요합니다. 문서 생성은 ASP.NET Core의 OpenAPI 기능이 담당하고, 브라우저에서 탐색하고 테스트하는 화면은 Swagger UI, Scalar, ReDoc 같은 별도 UI 도구가 담당하는 구조로 보는 것이 맞습니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_grid&quot;&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;.NET 8 이하에서 익숙한 방식&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;Swashbuckle 중심 구성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 ASP.NET Core 프로젝트에서는 AddSwaggerGen, UseSwagger, UseSwaggerUI 흐름이 가장 널리 쓰였습니다. 빠르게 문서를 띄우고 로컬 테스트를 붙이는 데 강점이 있어 여전히 많은 현업 프로젝트에서 사용됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;.NET 9 이상 최신 흐름&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;기본 제공 OpenAPI + 별도 UI&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 ASP.NET Core는 OpenAPI 문서 생성을 기본 제공하며, Swagger UI는 기본 내장이 아닙니다. 즉 문서 생성은 플랫폼 기본 기능으로 가져가고, UI는 필요에 따라 Swagger UI나 Scalar를 추가하는 방식이 더 깔끔합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_divider&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닷넷 관점에서 이 변화가 의미하는 바는 분명합니다. 이제는 단순히 Swagger 패키지를 붙이는 수준이 아니라, &lt;span class=&quot;wsinfo_point&quot;&gt;API 설명 메타데이터, 문서 생성, 문서 UI, 빌드 산출물, 클라이언트 코드 생성&lt;/span&gt;을 서로 분리해서 설계해야 한다는 뜻입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;ASP.NET Core 실무에서 꼭 넣어야 할 OpenAPI 구성 요소&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닷넷 프로젝트에서 Swagger/OpenAPI를 진짜 실무형으로 쓰려면 단순 활성화만으로는 부족합니다. 아래 항목들이 들어가야 고객사 문서, 사내 개발 문서, 운영 배포 문서가 각각 제 역할을 하게 됩니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_steps&quot;&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;01&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;런타임 문서와 빌드 산출물 분리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 환경에서는 런타임 OpenAPI 엔드포인트로 빠르게 확인하고, 배포 파이프라인에서는 빌드 시점에 JSON 또는 YAML 산출물을 생성해 아티팩트처럼 관리하는 구성이 좋습니다. 이렇게 해야 고객사용 정적 문서 배포나 계약 테스트 자동화가 쉬워집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;02&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;XML 주석 기반 설명 강화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C#은 XML 문서 주석을 활용할 수 있다는 장점이 큽니다. summary, remarks, param, response, example 같은 정보를 코드에 남기면 OpenAPI 문서에 자연스럽게 녹아들고, 코드와 문서의 동기화 수준도 높아집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;03&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;문서 변환기 기반 공통 규칙 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 ASP.NET Core의 OpenAPI 기능은 문서 전체, 개별 작업, 스키마 단위로 문서를 변형할 수 있는 transformer 구조를 제공합니다. 이걸 이용하면 공통 헤더 설명, 전역 보안 요구사항, 공통 응답 설명 같은 규칙을 일괄 적용하기 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;04&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;UI 도구 선택 기준 분리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swagger UI는 테스트 중심, ReDoc은 읽기 중심, Scalar는 최신형 문서 경험에 가깝습니다. 내부 개발팀 문서와 외부 고객사 문서를 같은 UI로 고정하지 말고, 사용 목적에 따라 UI 전략을 분리하는 편이 더 실무적입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;05&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;NSwag 활용 범위 검토&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닷넷 생태계에서는 NSwag도 여전히 강력합니다. 문서 생성뿐 아니라 C# 클라이언트 코드 생성, ReDoc 제공, 외부 스펙 기반 소비자 코드 생성까지 연결할 수 있어 고객사 SDK나 내부 연동 클라이언트를 빠르게 만들 때 특히 유리합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;닷넷 프로젝트에서 특히 주의해야 할 포인트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ASP.NET Core는 문서 생성 기능이 좋아진 대신, 버전별 접근 방식 차이를 이해하지 못하면 오히려 설정이 혼란스러워질 수 있습니다. 예를 들어 오래된 Swashbuckle 중심 예제를 그대로 최신 프로젝트에 복사하면 구조가 뒤섞일 수 있고, 반대로 최신 기본 제공 OpenAPI만 믿고 UI 전략을 안 세우면 고객사 전달 문서가 빈약해질 수 있습니다.&lt;/p&gt;
&lt;ul class=&quot;wsinfo_checklist&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 프로젝트는 Swashbuckle 중심, 신규 최신 프로젝트는 기본 OpenAPI 중심으로 판단하는 것이 안전합니다.&lt;/li&gt;
&lt;li&gt;문서 생성과 UI는 분리해서 생각해야 운영 구조가 깔끔해집니다.&lt;/li&gt;
&lt;li&gt;빌드 시 문서 산출물을 남겨야 CI/CD와 계약 테스트 자동화가 쉬워집니다.&lt;/li&gt;
&lt;li&gt;XML 문서 주석을 적극 활용하면 닷넷 프로젝트의 문서 완성도가 확 올라갑니다.&lt;/li&gt;
&lt;li&gt;고객사 제공 문서는 public 전용 문서로 따로 생성하는 것이 가장 안전합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;wsinfo_quote&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닷넷에서 Swagger/OpenAPI를 잘 쓴다는 것은 패키지 하나 설치하는 문제가 아니라, &lt;b&gt;플랫폼 기본 기능, UI 선택, 문서 산출물, 코드 주석, 고객사 전달 체계&lt;/b&gt;를 함께 설계하는 일에 가깝습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;대규모 엔터프라이즈 환경에서는 무엇을 더 고려해야 하나&lt;/h2&gt;
&lt;p class=&quot;wsinfo_section_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;엔드포인트 수가 많아질수록 문서는 단순히 예쁘게 보이는 것보다 잘 나뉘고 빨리 열리고 쉽게 찾을 수 있어야 합니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_matrix&quot;&gt;
&lt;div class=&quot;wsinfo_matrix_item&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;그룹화 전략&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tags만으로도 1차 분류는 가능하지만, admin&amp;middot;user&amp;middot;operation처럼 URL 또는 역할 기반으로 물리적으로 분리하는 편이 훨씬 강력합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_matrix_item&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;브랜드 반영&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 고객사에게 보여줄 문서는 회사의 기술 완성도를 대변합니다. 로고, 상단 색상, 파비콘, 제목까지 브랜드 일관성을 맞추는 것이 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_matrix_item&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;렌더링 성능&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서 크기가 커지면 브라우저 프리즈가 발생할 수 있습니다. 부가 기능을 끄고 확장 깊이를 조절하는 튜닝이 필요합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_table_wrap&quot;&gt;
&lt;table class=&quot;wsinfo_table&quot; 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;실무 효과&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;syntaxHighlight&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;대형 JSON 예시 렌더링 시 브라우저 부담을 줄여 응답성을 높입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DocExpansion&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;초기 로드 시 모든 항목이 펼쳐지는 것을 막아 첫 화면 속도를 안정화합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DefaultModelExpandDepth&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;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;Code-First와 Design-First, 무엇이 더 좋은가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 질문은 단순 취향 문제가 아닙니다. 프로젝트 운영 방식과 협업 구조를 결정하는 문제입니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_grid&quot;&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;Code-First&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;개발 속도는 빠르지만 계약 통제가 약해질 수 있습니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 먼저 만들고 문서를 따라오게 하는 방식입니다. 초기 개발 속도와 프로토타이핑에는 유리하지만, 고객사나 프론트엔드와 협업할 때는 합의된 계약이 늦게 생긴다는 단점이 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;Design-First&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;초기 조율 비용은 들지만 장기적으로 훨씬 강합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 쓰기 전에 OpenAPI 사양을 먼저 합의하는 방식입니다. 이 경우 문서가 곧 계약이 되므로 프론트엔드와 백엔드가 병렬로 움직일 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_divider&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 신규 서비스나 외부 고객사 연동이 많은 프로젝트라면 Design-First가 훨씬 유리합니다. 사양이 먼저 확정되면 Prism, Stoplight, ReadyAPI 같은 도구로 모킹 서버를 띄워 프론트엔드 개발을 즉시 시작할 수 있고, 백엔드는 Codegen이나 서버 스텁을 활용해 실제 구현에 집중할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 Code-First로 시작한 뒤 나중에 계약 중심 구조로 옮기려 하면 이미 의존성이 얽혀 있어 리팩토링 비용이 크게 증가합니다. 그래서 서비스 초기일수록 설계 우선의 가치가 더 큽니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;고객사 적용 단계에서 반드시 봐야 하는 것들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부 개발용 Swagger를 열어두는 것과, 외부 고객사에게 연동 문서로 제공하는 것은 완전히 다른 문제입니다. 여기서부터는 문서 품질이 아니라 &lt;span class=&quot;wsinfo_point&quot;&gt;보안, 버전 관리, 문서 분리, 운영 자동화&lt;/span&gt;가 핵심이 됩니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_steps&quot;&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;01&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;프로덕션 노출 통제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swagger UI와 api-docs를 운영 환경에 그대로 노출하면 공격자에게 시스템 구조를 제공하는 꼴이 됩니다. 운영에서는 비활성화하거나, 최소한 인증과 화이트리스트 기반 통제로 막아야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;02&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;예시 데이터 마스킹&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서 안의 example 데이터에 실제 이름, 전화번호, 이메일, 키 값이 들어가면 그 자체로 사고가 됩니다. 고객사 제공 문서는 샘플 데이터까지 별도 검증이 필요합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;03&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;버전 관리 전략 수립&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 고객사가 이미 연동 중이라면 작은 변경도 장애가 됩니다. URI 버전, Header 버전, 미디어 타입 버전 등 전략을 정하고, Deprecated 플래그와 마이그레이션 가이드를 함께 제공해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_steps_item&quot;&gt;
&lt;div class=&quot;wsinfo_steps_no&quot;&gt;04&lt;/div&gt;
&lt;div&gt;
&lt;h3 class=&quot;wsinfo_steps_title&quot; data-ke-size=&quot;size23&quot;&gt;내부용과 외부용 문서 분리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;admin, internal, operation API를 외부 고객 문서에 같이 노출하면 안 됩니다. 라우팅 기반으로 public 문서만 따로 생성하거나, 빌드 파이프라인에서 필터링된 스펙을 별도 배포해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul class=&quot;wsinfo_checklist&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;운영 환경에서는 Swagger UI를 기본적으로 닫아두는 것이 원칙입니다.&lt;/li&gt;
&lt;li&gt;열어야 한다면 인증, 접근 제어, IP 제한을 같이 걸어야 합니다.&lt;/li&gt;
&lt;li&gt;예시 데이터, 에러 응답, 샘플 토큰까지 전부 검토해야 합니다.&lt;/li&gt;
&lt;li&gt;구버전 폐기는 삭제보다 먼저 Deprecated와 유예 기간 안내가 필요합니다.&lt;/li&gt;
&lt;li&gt;고객사 문서는 Public API만 별도 분리해 제공하는 것이 가장 안전합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;이제는 Swagger 링크가 아니라 개발자 포털을 생각해야 한다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B2B 고객사에게 API를 인도할 때 단순히 Swagger 주소만 보내는 방식은 점점 한계를 드러냅니다. 실제 고객사는 문서만 필요한 것이 아니라, 연동 순서, 인증 절차, 샘플 시나리오, 버전 변경 이력, 앱 등록 방법까지 함께 이해해야 하기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 성숙한 조직은 Swagger UI를 종착점이 아니라 &lt;span class=&quot;wsinfo_point&quot;&gt;개발자 포털의 데이터 소스&lt;/span&gt;로 활용합니다. Redocly, Backstage, ReadMe 같은 포털 도구와 연동하면 API 참조 문서와 가이드 문서를 함께 제공할 수 있고, API Gateway와 결합하면 앱 등록과 키 발급까지 셀프서비스 형태로 연결할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;wsinfo_grid&quot;&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;Portal Strategy&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;문서를 서비스처럼 제공&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기술 문서를 링크 하나로 끝내지 않고, 고객사가 실제로 연동을 성공할 수 있도록 온보딩 경험 자체를 설계해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;wsinfo_cards_item&quot;&gt;
&lt;div class=&quot;wsinfo_cards_kicker&quot;&gt;CI/CD Automation&lt;/div&gt;
&lt;h3 class=&quot;wsinfo_cards_title&quot; data-ke-size=&quot;size23&quot;&gt;문서 무결성은 자동으로 검증&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dredd, Schemathesis 같은 계약 테스트 도구를 파이프라인에 넣으면, 스펙과 실제 응답이 어긋나는 순간 빌드를 실패시켜 문서 신뢰도를 지킬 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;wsinfo_section&quot;&gt;
&lt;h2 class=&quot;wsinfo_section_title&quot; data-ke-size=&quot;size26&quot;&gt;결국 핵심은 문서를 얼마나 잘 쓰느냐가 아니라, 얼마나 잘 운영하느냐입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swagger와 OpenAPI를 도입했다고 해서 바로 문서화가 잘되는 것은 아닙니다. 진짜 차이는 그다음부터 발생합니다. 문서를 코드와 함께 관리하는지, 고객사 관점으로 분리해 주는지, 보안과 버전 전략이 붙어 있는지, 그리고 CI/CD를 통해 자동 검증되는지에 따라 결과가 완전히 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 좋은 API 문서는 세 가지를 동시에 만족해야 합니다. &lt;span class=&quot;wsinfo_point&quot;&gt;개발자는 빠르게 이해할 수 있어야 하고, 운영팀은 안전하게 통제할 수 있어야 하며, 고객사는 불안 없이 연동할 수 있어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 기준으로 보면 Swagger와 OpenAPI는 단순 문서화 도구가 아니라, 서비스 신뢰도와 기술 성숙도를 드러내는 핵심 인프라라고 보는 편이 더 정확합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&quot;wsinfo_footer&quot;&gt;태그 추천: #Swagger #OpenAPI #웹서비스 #API문서화 #Springdoc #Nodejs #API보안 #버전관리 #CICD #개발자포털&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>api문서화</category>
      <category>api보안</category>
      <category>Nodejs</category>
      <category>OpenAPI</category>
      <category>springboot</category>
      <category>springdoc</category>
      <category>swagger</category>
      <category>개발자포털</category>
      <category>버전관리</category>
      <category>웹서비스개발</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/581</guid>
      <comments>https://odinbox.tistory.com/581#entry581comment</comments>
      <pubDate>Sat, 18 Apr 2026 23:04:07 +0900</pubDate>
    </item>
    <item>
      <title>대규모 트래픽 처리를 위한 로드밸런싱과 DB 분산 전략</title>
      <link>https://odinbox.tistory.com/580</link>
      <description>&lt;div&gt;
&lt;style&gt;
  .balancing_wrap { font-family: 'Pretendard', 'Apple SD Gothic Neo', -apple-system, sans-serif; color: #1a1a1a; line-height: 1.85; max-width: 780px; margin: 0 auto; font-size: 16.5px; word-break: keep-all; }
  .balancing_wrap h2 { font-size: 26px; font-weight: 800; margin: 56px 0 18px; padding-bottom: 12px; border-bottom: 3px solid #1a1a1a; letter-spacing: -0.02em; }
  .balancing_wrap h3 { font-size: 21px; font-weight: 700; margin: 44px 0 14px; color: #1a1a1a; }
  .balancing_wrap h4 { font-size: 17.5px; font-weight: 700; margin: 32px 0 10px; color: #2d2d2d; }
  .balancing_wrap p { margin: 0 0 16px; }
  .balancing_wrap strong { color: #0d6efd; font-weight: 700; }
  .balancing_wrap hr { border: none; border-top: 1px solid #e0e0e0; margin: 48px 0; }
  .balancing_wrap code { background: #f1f3f5; padding: 2px 6px; border-radius: 4px; font-family: 'JetBrains Mono', 'D2Coding', monospace; font-size: 14px; }

  .balancing_thumbnail { width: 100%; max-height: 420px; object-fit: cover; border-radius: 12px; margin: 0 0 36px; display: block; }

  .balancing_intro { background: linear-gradient(135deg, #f0f4ff 0%, #e8f0fe 100%); border-left: 5px solid #1a73e8; border-radius: 0 12px 12px 0; padding: 28px 32px; margin: 0 0 36px; font-size: 15.5px; color: #303030; }
  .balancing_intro p:last-child { margin-bottom: 0; }

  .balancing_code { background: #1e1e2e; color: #cdd6f4; border-radius: 10px; padding: 22px 26px; margin: 18px 0 24px; overflow-x: auto; font-family: 'JetBrains Mono', 'D2Coding', 'Fira Code', monospace; font-size: 13.8px; line-height: 1.7; white-space: pre; }
  .balancing_code .balancing_cm { color: #6c7086; }
  .balancing_code .balancing_kw { color: #cba6f7; }
  .balancing_code .balancing_st { color: #a6e3a1; }
  .balancing_code .balancing_an { color: #f9e2af; }
  .balancing_code .balancing_tp { color: #89b4fa; }
  .balancing_code .balancing_nm { color: #fab387; }

  .balancing_diagram { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 10px; padding: 24px 28px; margin: 18px 0 24px; font-family: 'JetBrains Mono', 'D2Coding', monospace; font-size: 13.5px; line-height: 1.65; color: #495057; white-space: pre; overflow-x: auto; text-align: center; }

  .balancing_tbl { overflow-x: auto; margin: 18px 0 24px; border-radius: 10px; border: 1px solid #dee2e6; }
  .balancing_tbl table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
  .balancing_tbl thead { background: #1a73e8; color: #fff; }
  .balancing_tbl th { padding: 13px 16px; text-align: left; font-weight: 600; white-space: nowrap; }
  .balancing_tbl td { padding: 12px 16px; border-top: 1px solid #e9ecef; }
  .balancing_tbl tbody tr:hover { background: #f0f4ff; }
  .balancing_tbl tbody tr:nth-child(even) { background: #f8f9fa; }
  .balancing_tbl tbody tr:nth-child(even):hover { background: #e8f0fe; }

  .balancing_note { background: #fff8e1; border-left: 5px solid #ffc107; border-radius: 0 10px 10px 0; padding: 18px 22px; margin: 18px 0 24px; font-size: 15px; }
  .balancing_warn { background: #fce4ec; border-left: 5px solid #e53935; border-radius: 0 10px 10px 0; padding: 18px 22px; margin: 18px 0 24px; font-size: 15px; }

  .balancing_checklist { margin: 14px 0 24px; padding: 0; list-style: none; }
  .balancing_checklist li { padding: 8px 0 8px 30px; position: relative; font-size: 15px; }
  .balancing_checklist li::before { content: '\25B6'; position: absolute; left: 6px; color: #1a73e8; font-size: 10px; top: 12px; }

  .balancing_summary { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); color: #e0e0e0; border-radius: 12px; padding: 30px 34px; margin: 24px 0; }
  .balancing_summary h4 { color: #82b1ff; margin-top: 0; font-size: 18px; }
  .balancing_summary ol { padding-left: 20px; margin: 0; }
  .balancing_summary li { margin-bottom: 10px; line-height: 1.7; }
  .balancing_summary strong { color: #64ffda; }

  .balancing_badge { display: inline-block; background: #1a73e8; color: #fff; width: 32px; height: 32px; line-height: 32px; text-align: center; border-radius: 50%; font-size: 15px; font-weight: 700; margin-right: 10px; vertical-align: middle; }

  .balancing_ref { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 10px; padding: 24px 28px; margin: 24px 0; }
  .balancing_ref h4 { margin-top: 0; color: #1a73e8; }
  .balancing_ref ul { padding-left: 20px; margin: 0; }
  .balancing_ref li { margin-bottom: 8px; font-size: 14.5px; line-height: 1.6; }
  .balancing_ref a { color: #1a73e8; text-decoration: none; }
  .balancing_ref a:hover { text-decoration: underline; }

  .balancing_tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 32px; }
  .balancing_tags span { background: #e8f0fe; color: #1a73e8; padding: 6px 14px; border-radius: 20px; font-size: 13px; font-weight: 600; }
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;balancing_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oEmLP/dJMcaaLGiP3/MUklHYY2KoR2kTHKSvdIAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oEmLP/dJMcaaLGiP3/MUklHYY2KoR2kTHKSvdIAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oEmLP/dJMcaaLGiP3/MUklHYY2KoR2kTHKSvdIAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoEmLP%2FdJMcaaLGiP3%2FMUklHYY2KoR2kTHKSvdIAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;div class=&quot;balancing_intro&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 개발하다 보면 처음에는 단일 서버 하나로도 충분합니다. 하지만 사용자가 늘고, 동시 접속이 수백에서 수천 단위를 넘어가기 시작하면 &quot;서버가 버틸 수 있을까?&quot;라는 고민이 현실로 다가옵니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 업무를 하면서 규모 있는 서비스를 만들다 보면, 단순히 기능 구현에만 집중할 수 없습니다. 동시 접속자가 몰릴 때 응답 지연이 발생하고, DB 커넥션이 부족해져 장애로 이어지는 상황을 한두 번 겪고 나면 &lt;b&gt;트래픽 분산&lt;/b&gt;과 &lt;b&gt;DB 처리 전략&lt;/b&gt;이 아키텍처 설계의 핵심이라는 걸 체감하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 로드밸런싱의 기본 개념부터 DB 커넥션 관리, 읽기/쓰기 분리, 캐싱 전략까지 실무에서 활용할 수 있는 기술들을 정리해 보겠습니다. 이론에 그치지 않고 &lt;b&gt;왜 이 기술이 필요한지&lt;/b&gt;, 그리고 &lt;b&gt;어떤 상황에서 어떤 선택을 해야 하는지&lt;/b&gt; 판단 기준을 함께 다루겠습니다. 또한 IIS/ASP.NET Core 환경과 Node.js 환경에서의 실제 구현 방법도 함께 정리하였습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;1&lt;/span&gt;로드밸런싱(Load Balancing)이란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런싱은 다수의 서버에 클라이언트 요청을 분산하여 특정 서버에 부하가 집중되는 것을 방지하는 기술입니다. 단일 서버 구성에서는 해당 서버가 다운되면 서비스 전체가 중단되지만, 로드밸런서를 도입하면 &lt;b&gt;고가용성(High Availability)&lt;/b&gt;과 &lt;b&gt;수평 확장(Scale-Out)&lt;/b&gt;이 가능해집니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로드밸런서의 동작 위치&lt;/h4&gt;
&lt;div class=&quot;balancing_diagram&quot;&gt;[클라이언트] | v [로드밸런서] -- L4(TCP/UDP) 또는 L7(HTTP/HTTPS) 계층 | +--+--+ v v v [WAS1][WAS2][WAS3] -- 동일 애플리케이션 서버 그룹&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;L4 로드밸런싱&lt;/b&gt;은 IP 주소와 포트 기반으로 분배하며, 처리 속도가 빠르고 단순합니다. AWS NLB, HAProxy(TCP 모드)가 대표적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;L7 로드밸런싱&lt;/b&gt;은 HTTP 헤더, URL 경로, 쿠키 등 애플리케이션 계층 정보를 기반으로 분배합니다. URL 패턴별로 다른 서버 그룹에 라우팅 할 수 있으며, AWS ALB, Nginx가 대표적입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주요 분배 알고리즘&lt;/h4&gt;
&lt;div class=&quot;balancing_tbl&quot;&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;적합한 상황&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Round Robin&lt;/b&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;b&gt;Weighted Round Robin&lt;/b&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;b&gt;Least Connections&lt;/b&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;b&gt;IP Hash&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;클라이언트 IP 기반 해시로 고정 서버를 할당합니다&lt;/td&gt;
&lt;td&gt;세션 유지가 필요할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Least Response Time&lt;/b&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;h4 data-ke-size=&quot;size20&quot;&gt;세션 관리 문제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런싱 환경에서 가장 먼저 부딪히는 문제가 &lt;b&gt;세션 관리&lt;/b&gt;입니다. 사용자가 WAS1에서 로그인했는데 다음 요청이 WAS2로 가면 세션이 없어 로그인이 풀리게 됩니다. 해결 방법은 크게 세 가지입니다.&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;Sticky Session&lt;/b&gt; &amp;mdash; 로드밸런서가 특정 사용자를 동일 서버에 고정하는 방식입니다. 구현이 간단하지만, 특정 서버에 부하가 몰릴 수 있고 해당 서버가 다운되면 세션이 유실됩니다.&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;Session Clustering&lt;/b&gt; &amp;mdash; WAS 간 세션 데이터를 복제하고 공유하는 방식입니다. Tomcat의 경우 DeltaManager를 활용할 수 있지만, 서버 수가 늘어나면 동기화 오버헤드가 기하급수적으로 증가합니다.&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;External Session Store&lt;/b&gt; &amp;mdash; Redis나 Memcached 같은 외부 저장소에 세션을 저장하는 방식입니다. 가장 널리 사용되며, WAS가 어디로 라우팅되든 동일한 세션 데이터를 조회할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;balancing_diagram&quot;&gt;[WAS1] --+ [WAS2] --+--&amp;gt; [Redis Cluster] -- 세션 저장소 [WAS3] --+&lt;/div&gt;
&lt;div class=&quot;balancing_note&quot;&gt;&lt;b&gt;참고&lt;/b&gt; - 실무에서는 JWT 토큰 기반 인증으로 아예 서버 측 세션을 없애는 Stateless 구조를 채택하는 경우도 많습니다. 세션 저장소 자체가 불필요해지므로 구조가 단순해집니다. 다만 토큰 탈취 시 즉시 무효화가 어렵다는 트레이드오프가 있어, Refresh Token 전략이나 Token Blacklist 등 보완 설계가 필요합니다.&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;2&lt;/span&gt;IIS + ASP.NET Core 환경에서의 로드밸런싱&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows Server 기반의 IIS 환경에서는 &lt;b&gt;ARR(Application Request Routing)&lt;/b&gt; 모듈을 통해 L7 로드밸런싱을 구성할 수 있습니다. ARR은 IIS의 확장 모듈로, 리버스 프록시 및 로드밸런서 역할을 수행합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;IIS ARR 기반 서버 팜 구성&lt;/h4&gt;
&lt;div class=&quot;balancing_diagram&quot;&gt;[클라이언트] | v [IIS + ARR] -- 로드밸런서 역할 | +--+--+ v v v [IIS Node1][IIS Node2][IIS Node3] ASP.NET ASP.NET ASP.NET Core App Core App Core App&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ARR에서 서버 팜(Server Farm)을 생성하고, 각 백엔드 서버를 등록하면 자동으로 Health Check와 함께 요청을 분배합니다. 분배 알고리즘은 Weighted Round Robin, Least Current Request 등을 IIS 관리자에서 선택할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ASP.NET Core 분산 세션 구성 (Redis)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ASP.NET Core에서는 &lt;b&gt;Microsoft.Extensions.Caching.StackExchangeRedis&lt;/b&gt; 패키지를 통해 분산 세션을 구성합니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;// Program.cs builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddStackExchangeRedisCache&lt;/span&gt;(options =&amp;gt; { options.&lt;span class=&quot;balancing_tp&quot;&gt;Configuration&lt;/span&gt; = &lt;span class=&quot;balancing_st&quot;&gt;&quot;redis-server:6379&quot;&lt;/span&gt;; options.&lt;span class=&quot;balancing_tp&quot;&gt;InstanceName&lt;/span&gt; = &lt;span class=&quot;balancing_st&quot;&gt;&quot;MyApp_&quot;&lt;/span&gt;; }); builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddSession&lt;/span&gt;(options =&amp;gt; { options.&lt;span class=&quot;balancing_tp&quot;&gt;IdleTimeout&lt;/span&gt; = &lt;span class=&quot;balancing_tp&quot;&gt;TimeSpan&lt;/span&gt;.&lt;span class=&quot;balancing_kw&quot;&gt;FromMinutes&lt;/span&gt;(&lt;span class=&quot;balancing_nm&quot;&gt;30&lt;/span&gt;); options.&lt;span class=&quot;balancing_tp&quot;&gt;Cookie&lt;/span&gt;.&lt;span class=&quot;balancing_tp&quot;&gt;HttpOnly&lt;/span&gt; = &lt;span class=&quot;balancing_kw&quot;&gt;true&lt;/span&gt;; options.&lt;span class=&quot;balancing_tp&quot;&gt;Cookie&lt;/span&gt;.&lt;span class=&quot;balancing_tp&quot;&gt;IsEssential&lt;/span&gt; = &lt;span class=&quot;balancing_kw&quot;&gt;true&lt;/span&gt;; }); app.&lt;span class=&quot;balancing_kw&quot;&gt;UseSession&lt;/span&gt;();&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ASP.NET Core Data Protection Key 공유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런싱 환경에서 ASP.NET Core를 운영할 때 반드시 설정해야 하는 것이 &lt;b&gt;Data Protection Key 공유&lt;/b&gt;입니다. 각 인스턴스가 서로 다른 키를 사용하면 인증 쿠키를 복호화할 수 없어 세션이 풀리게 됩니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddDataProtection&lt;/span&gt;() .&lt;span class=&quot;balancing_kw&quot;&gt;PersistKeysToStackExchangeRedis&lt;/span&gt;( &lt;span class=&quot;balancing_tp&quot;&gt;ConnectionMultiplexer&lt;/span&gt;.&lt;span class=&quot;balancing_kw&quot;&gt;Connect&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;redis-server:6379&quot;&lt;/span&gt;), &lt;span class=&quot;balancing_st&quot;&gt;&quot;DataProtection-Keys&quot;&lt;/span&gt; ) .&lt;span class=&quot;balancing_kw&quot;&gt;SetApplicationName&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;MyApp&quot;&lt;/span&gt;);&lt;/div&gt;
&lt;div class=&quot;balancing_warn&quot;&gt;&lt;b&gt;주의&lt;/b&gt; &amp;mdash; Data Protection Key를 공유하지 않으면 IIS ARR 환경에서 Sticky Session 없이 운영할 때 로그인이 반복적으로 풀리는 현상이 발생합니다. 이 문제는 실무에서 매우 자주 발생하므로 반드시 확인해야 합니다.&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;IIS 환경에서의 Health Check 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ASP.NET Core에는 내장 Health Check 미들웨어가 있으며, ARR의 URL Test 기능과 연동할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddHealthChecks&lt;/span&gt;() .&lt;span class=&quot;balancing_kw&quot;&gt;AddSqlServer&lt;/span&gt;(connectionString, name: &lt;span class=&quot;balancing_st&quot;&gt;&quot;sqldb&quot;&lt;/span&gt;) .&lt;span class=&quot;balancing_kw&quot;&gt;AddRedis&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;redis-server:6379&quot;&lt;/span&gt;, name: &lt;span class=&quot;balancing_st&quot;&gt;&quot;redis&quot;&lt;/span&gt;); app.&lt;span class=&quot;balancing_kw&quot;&gt;MapHealthChecks&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;/health&quot;&lt;/span&gt;);&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ARR 서버 팜의 Health Test 설정에서 URL을 &lt;code&gt;/health&lt;/code&gt;로 지정하면, 장애가 발생한 노드를 자동으로 분배 대상에서 제외합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;3&lt;/span&gt;Node.js 환경에서의 로드밸런싱&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js는 싱글 스레드 이벤트 루프 기반으로 동작하기 때문에, 멀티 코어 CPU를 활용하려면 별도의 분산 처리가 필요합니다. 대표적인 방법은 &lt;b&gt;Cluster 모듈&lt;/b&gt;과 &lt;b&gt;PM2&lt;/b&gt;, 그리고 앞단에 &lt;b&gt;Nginx 리버스 프록시&lt;/b&gt;를 두는 구성입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Node.js Cluster 모듈&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; cluster = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'cluster'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; os = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'os'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; express = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'express'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;if&lt;/span&gt; (cluster.&lt;span class=&quot;balancing_tp&quot;&gt;isPrimary&lt;/span&gt;) { &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; cpuCount = os.&lt;span class=&quot;balancing_kw&quot;&gt;cpus&lt;/span&gt;().&lt;span class=&quot;balancing_tp&quot;&gt;length&lt;/span&gt;; console.&lt;span class=&quot;balancing_kw&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;`Primary ${process.pid} &amp;mdash; forking ${cpuCount} workers`&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;balancing_kw&quot;&gt;let&lt;/span&gt; i = &lt;span class=&quot;balancing_nm&quot;&gt;0&lt;/span&gt;; i &amp;lt; cpuCount; i++) { cluster.&lt;span class=&quot;balancing_kw&quot;&gt;fork&lt;/span&gt;(); } cluster.&lt;span class=&quot;balancing_kw&quot;&gt;on&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'exit'&lt;/span&gt;, (worker) =&amp;gt; { console.&lt;span class=&quot;balancing_kw&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;`Worker ${worker.process.pid} exited. Restarting...`&lt;/span&gt;); cluster.&lt;span class=&quot;balancing_kw&quot;&gt;fork&lt;/span&gt;(); }); } &lt;span class=&quot;balancing_kw&quot;&gt;else&lt;/span&gt; { &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; app = &lt;span class=&quot;balancing_kw&quot;&gt;express&lt;/span&gt;(); app.&lt;span class=&quot;balancing_kw&quot;&gt;get&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'/'&lt;/span&gt;, (req, res) =&amp;gt; { res.&lt;span class=&quot;balancing_kw&quot;&gt;send&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;`Handled by worker ${process.pid}`&lt;/span&gt;); }); app.&lt;span class=&quot;balancing_kw&quot;&gt;listen&lt;/span&gt;(&lt;span class=&quot;balancing_nm&quot;&gt;3000&lt;/span&gt;); }&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PM2를 활용한 클러스터 모드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PM2는 Node.js 프로세스 매니저로, 클러스터 모드를 간편하게 설정할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;module.exports = { apps: [{ &lt;span class=&quot;balancing_tp&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;my-app&quot;&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;script&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;./app.js&quot;&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;instances&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;max&quot;&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;exec_mode&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;cluster&quot;&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;max_memory_restart&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;500M&quot;&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;env&lt;/span&gt;: { &lt;span class=&quot;balancing_tp&quot;&gt;NODE_ENV&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;production&quot;&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;PORT&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;3000&lt;/span&gt; } }] };&lt;/div&gt;
&lt;div class=&quot;balancing_code&quot;&gt;$ pm2 start ecosystem.config.js $ pm2 monit $ pm2 reload my-app&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Nginx 리버스 프록시 + Node.js 다중 인스턴스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로덕션 환경에서는 Nginx를 앞단에 두고 여러 Node.js 인스턴스(또는 서버)로 요청을 분배하는 것이 일반적입니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;upstream&lt;/span&gt; nodejs_backend { &lt;span class=&quot;balancing_kw&quot;&gt;least_conn&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;balancing_nm&quot;&gt;127.0.0.1&lt;/span&gt;:&lt;span class=&quot;balancing_nm&quot;&gt;3001&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;balancing_nm&quot;&gt;127.0.0.1&lt;/span&gt;:&lt;span class=&quot;balancing_nm&quot;&gt;3002&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;balancing_nm&quot;&gt;127.0.0.1&lt;/span&gt;:&lt;span class=&quot;balancing_nm&quot;&gt;3003&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;balancing_nm&quot;&gt;127.0.0.1&lt;/span&gt;:&lt;span class=&quot;balancing_nm&quot;&gt;3004&lt;/span&gt;; } &lt;span class=&quot;balancing_kw&quot;&gt;server&lt;/span&gt; { &lt;span class=&quot;balancing_kw&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;balancing_nm&quot;&gt;80&lt;/span&gt;; &lt;span class=&quot;balancing_tp&quot;&gt;server_name&lt;/span&gt; example.com; &lt;span class=&quot;balancing_kw&quot;&gt;location&lt;/span&gt; / { &lt;span class=&quot;balancing_kw&quot;&gt;proxy_pass&lt;/span&gt; http://nodejs_backend; &lt;span class=&quot;balancing_tp&quot;&gt;proxy_http_version&lt;/span&gt; &lt;span class=&quot;balancing_nm&quot;&gt;1.1&lt;/span&gt;; &lt;span class=&quot;balancing_tp&quot;&gt;proxy_set_header&lt;/span&gt; Upgrade $http_upgrade; &lt;span class=&quot;balancing_tp&quot;&gt;proxy_set_header&lt;/span&gt; Connection &lt;span class=&quot;balancing_st&quot;&gt;'upgrade'&lt;/span&gt;; &lt;span class=&quot;balancing_tp&quot;&gt;proxy_set_header&lt;/span&gt; Host $host; &lt;span class=&quot;balancing_tp&quot;&gt;proxy_cache_bypass&lt;/span&gt; $http_upgrade; } }&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Node.js 분산 세션 관리 (express-session + Redis)&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; session = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'express-session'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; RedisStore = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'connect-redis'&lt;/span&gt;).default; &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; { &lt;span class=&quot;balancing_tp&quot;&gt;createClient&lt;/span&gt; } = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'redis'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; redisClient = &lt;span class=&quot;balancing_kw&quot;&gt;createClient&lt;/span&gt;({ &lt;span class=&quot;balancing_tp&quot;&gt;url&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'redis://redis-server:6379'&lt;/span&gt; }); &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; redisClient.&lt;span class=&quot;balancing_kw&quot;&gt;connect&lt;/span&gt;(); app.&lt;span class=&quot;balancing_kw&quot;&gt;use&lt;/span&gt;(&lt;span class=&quot;balancing_kw&quot;&gt;session&lt;/span&gt;({ &lt;span class=&quot;balancing_tp&quot;&gt;store&lt;/span&gt;: &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;RedisStore&lt;/span&gt;({ &lt;span class=&quot;balancing_tp&quot;&gt;client&lt;/span&gt;: redisClient }), &lt;span class=&quot;balancing_tp&quot;&gt;secret&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'your-secret-key'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;resave&lt;/span&gt;: &lt;span class=&quot;balancing_kw&quot;&gt;false&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;saveUninitialized&lt;/span&gt;: &lt;span class=&quot;balancing_kw&quot;&gt;false&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;cookie&lt;/span&gt;: { &lt;span class=&quot;balancing_tp&quot;&gt;secure&lt;/span&gt;: &lt;span class=&quot;balancing_kw&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;maxAge&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;1800000&lt;/span&gt; } }));&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;4&lt;/span&gt;DB 커넥션 관리 &amp;mdash; Connection Pool의 중요성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트래픽이 증가하면 WAS보다 &lt;b&gt;DB가 먼저 병목&lt;/b&gt;이 되는 경우가 많습니다. DB 커넥션은 생성 비용이 높은 자원입니다. TCP 3-way Handshake, 인증, 세션 초기화 과정을 매 요청마다 반복하면 성능이 급격히 저하됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Connection Pool 기본 구조&lt;/h4&gt;
&lt;div class=&quot;balancing_diagram&quot;&gt;[Application Thread 1] --+ [Application Thread 2] --+--&amp;gt; [Connection Pool] --&amp;gt; [DB] [Application Thread 3] --+ (미리 생성된 커넥션 N개를 재사용)&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;HikariCP 설정 예시 (Spring Boot / Java)&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;spring&lt;/span&gt;: &lt;span class=&quot;balancing_kw&quot;&gt;datasource&lt;/span&gt;: &lt;span class=&quot;balancing_kw&quot;&gt;hikari&lt;/span&gt;: &lt;span class=&quot;balancing_tp&quot;&gt;minimum-idle&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;maximum-pool-size&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;connection-timeout&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;3000&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;idle-timeout&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;600000&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;max-lifetime&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;1800000&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;leak-detection-threshold&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;5000&lt;/span&gt;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ASP.NET Core 커넥션 풀 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ASP.NET Core에서 SQL Server를 사용하는 경우, 커넥션 풀은 &lt;b&gt;연결 문자열&lt;/b&gt;에서 설정합니다. ADO.NET이 내부적으로 커넥션 풀을 관리합니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;{ &lt;span class=&quot;balancing_st&quot;&gt;&quot;ConnectionStrings&quot;&lt;/span&gt;: { &lt;span class=&quot;balancing_st&quot;&gt;&quot;Default&quot;&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;&quot;Server=db-server;Database=MyDb;User Id=sa;Password=***;Min Pool Size=10;Max Pool Size=100;Connection Timeout=15;Connection Lifetime=300;&quot;&lt;/span&gt; } }&lt;/div&gt;
&lt;div class=&quot;balancing_code&quot;&gt;builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddDbContext&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;AppDbContext&lt;/span&gt;&amp;gt;(options =&amp;gt; options.&lt;span class=&quot;balancing_kw&quot;&gt;UseSqlServer&lt;/span&gt;( builder.Configuration.&lt;span class=&quot;balancing_kw&quot;&gt;GetConnectionString&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;Default&quot;&lt;/span&gt;), sqlOptions =&amp;gt; sqlOptions.&lt;span class=&quot;balancing_kw&quot;&gt;EnableRetryOnFailure&lt;/span&gt;( maxRetryCount: &lt;span class=&quot;balancing_nm&quot;&gt;3&lt;/span&gt;, maxRetryDelay: &lt;span class=&quot;balancing_tp&quot;&gt;TimeSpan&lt;/span&gt;.&lt;span class=&quot;balancing_kw&quot;&gt;FromSeconds&lt;/span&gt;(&lt;span class=&quot;balancing_nm&quot;&gt;5&lt;/span&gt;), errorNumbersToAdd: &lt;span class=&quot;balancing_kw&quot;&gt;null&lt;/span&gt; ) ) );&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Node.js 커넥션 풀 설정 (PostgreSQL)&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; { &lt;span class=&quot;balancing_tp&quot;&gt;Pool&lt;/span&gt; } = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'pg'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; pool = &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;Pool&lt;/span&gt;({ &lt;span class=&quot;balancing_tp&quot;&gt;host&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'db-server'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;port&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;5432&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;database&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'mydb'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;user&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'admin'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;password&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'***'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;min&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;max&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;30&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;idleTimeoutMillis&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;30000&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;connectionTimeoutMillis&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;5000&lt;/span&gt;, }); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; client = &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; pool.&lt;span class=&quot;balancing_kw&quot;&gt;connect&lt;/span&gt;(); &lt;span class=&quot;balancing_kw&quot;&gt;try&lt;/span&gt; { &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; result = &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; client.&lt;span class=&quot;balancing_kw&quot;&gt;query&lt;/span&gt;( &lt;span class=&quot;balancing_st&quot;&gt;'SELECT * FROM products WHERE id = $1'&lt;/span&gt;, [id] ); &lt;span class=&quot;balancing_kw&quot;&gt;return&lt;/span&gt; result.rows[&lt;span class=&quot;balancing_nm&quot;&gt;0&lt;/span&gt;]; } &lt;span class=&quot;balancing_kw&quot;&gt;finally&lt;/span&gt; { client.&lt;span class=&quot;balancing_kw&quot;&gt;release&lt;/span&gt;(); }&lt;/div&gt;
&lt;div class=&quot;balancing_note&quot;&gt;&lt;b&gt;참고&lt;/b&gt; &amp;mdash; maximum-pool-size 설정은 단순히 크게 잡는 것이 능사가 아닙니다. DB 서버의 max_connections 값과 애플리케이션 인스턴스 수를 함께 고려해야 합니다. 예를 들어 DB max_connections가 200이고 인스턴스가 5대라면, 인스턴스당 풀 크기는 200 / 5 = 40, 여유분을 감안하면 30~35 수준이 적절합니다.&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;커넥션 누수(Connection Leak) 방지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 자주 발생하는 장애 원인 중 하나가 &lt;b&gt;커넥션 누수&lt;/b&gt;입니다. 트랜잭션을 열어놓고 예외 발생 시 커넥션을 반환하지 않으면, 풀의 커넥션이 하나씩 고갈되다가 결국 전체 서비스가 멈추게 됩니다.&lt;/p&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_cm&quot;&gt;// [C#] 잘못된 예 &amp;mdash; 예외 발생 시 커넥션 미반환&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; conn = &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;SqlConnection&lt;/span&gt;(connString); conn.&lt;span class=&quot;balancing_kw&quot;&gt;Open&lt;/span&gt;(); &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; cmd = conn.&lt;span class=&quot;balancing_kw&quot;&gt;CreateCommand&lt;/span&gt;(); cmd.&lt;span class=&quot;balancing_tp&quot;&gt;CommandText&lt;/span&gt; = &lt;span class=&quot;balancing_st&quot;&gt;&quot;SELECT ...&quot;&lt;/span&gt;; cmd.&lt;span class=&quot;balancing_kw&quot;&gt;ExecuteReader&lt;/span&gt;(); &lt;span class=&quot;balancing_cm&quot;&gt;// [C#] 올바른 예 &amp;mdash; using 문 사용&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; conn = &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;SqlConnection&lt;/span&gt;(connString); &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; conn.&lt;span class=&quot;balancing_kw&quot;&gt;OpenAsync&lt;/span&gt;(); &lt;span class=&quot;balancing_kw&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; cmd = conn.&lt;span class=&quot;balancing_kw&quot;&gt;CreateCommand&lt;/span&gt;(); cmd.&lt;span class=&quot;balancing_tp&quot;&gt;CommandText&lt;/span&gt; = &lt;span class=&quot;balancing_st&quot;&gt;&quot;SELECT ...&quot;&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; cmd.&lt;span class=&quot;balancing_kw&quot;&gt;ExecuteReaderAsync&lt;/span&gt;();&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;5&lt;/span&gt;DB 분산 전략 &amp;mdash; 읽기/쓰기 분리 (Read Replica)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 웹 서비스에서 DB 요청의 &lt;b&gt;70~80%는 읽기(SELECT)&lt;/b&gt; 작업입니다. 이 읽기 부하를 별도의 복제본(Replica)으로 분리하면 Master DB의 부하를 크게 줄일 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;balancing_diagram&quot;&gt;+--- [쓰기 요청] --&amp;gt; [Master DB] [Application] | | (비동기 복제) +--- [읽기 요청] --&amp;gt; [Replica DB 1] [Replica DB 2]&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ASP.NET Core에서의 읽기/쓰기 분리&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddDbContext&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;WriteDbContext&lt;/span&gt;&amp;gt;(options =&amp;gt; options.&lt;span class=&quot;balancing_kw&quot;&gt;UseSqlServer&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;Server=master-db;...&quot;&lt;/span&gt;)); builder.Services.&lt;span class=&quot;balancing_kw&quot;&gt;AddDbContext&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;ReadDbContext&lt;/span&gt;&amp;gt;(options =&amp;gt; options.&lt;span class=&quot;balancing_kw&quot;&gt;UseSqlServer&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;&quot;Server=replica-db;...&quot;&lt;/span&gt;) .&lt;span class=&quot;balancing_kw&quot;&gt;UseQueryTrackingBehavior&lt;/span&gt;( &lt;span class=&quot;balancing_tp&quot;&gt;QueryTrackingBehavior&lt;/span&gt;.NoTracking ));&lt;/div&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;public class&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;OrderService&lt;/span&gt; { &lt;span class=&quot;balancing_kw&quot;&gt;private readonly&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;WriteDbContext&lt;/span&gt; _writeDb; &lt;span class=&quot;balancing_kw&quot;&gt;private readonly&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;ReadDbContext&lt;/span&gt; _readDb; &lt;span class=&quot;balancing_cm&quot;&gt;// 읽기 -- Replica로 라우팅&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;public async&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;Task&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;Order&lt;/span&gt;&amp;gt;&amp;gt; &lt;span class=&quot;balancing_kw&quot;&gt;GetOrders&lt;/span&gt;(&lt;span class=&quot;balancing_tp&quot;&gt;long&lt;/span&gt; userId) =&amp;gt; &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; _readDb.Orders .&lt;span class=&quot;balancing_kw&quot;&gt;Where&lt;/span&gt;(o =&amp;gt; o.UserId == userId) .&lt;span class=&quot;balancing_kw&quot;&gt;ToListAsync&lt;/span&gt;(); &lt;span class=&quot;balancing_cm&quot;&gt;// 쓰기 -- Master로 라우팅&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;public async&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;CreateOrder&lt;/span&gt;(&lt;span class=&quot;balancing_tp&quot;&gt;Order&lt;/span&gt; order) { _writeDb.Orders.&lt;span class=&quot;balancing_kw&quot;&gt;Add&lt;/span&gt;(order); &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; _writeDb.&lt;span class=&quot;balancing_kw&quot;&gt;SaveChangesAsync&lt;/span&gt;(); } }&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Node.js에서의 읽기/쓰기 분리 (Sequelize)&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; { &lt;span class=&quot;balancing_tp&quot;&gt;Sequelize&lt;/span&gt; } = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'sequelize'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; sequelize = &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;Sequelize&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'mydb'&lt;/span&gt;, &lt;span class=&quot;balancing_kw&quot;&gt;null&lt;/span&gt;, &lt;span class=&quot;balancing_kw&quot;&gt;null&lt;/span&gt;, { &lt;span class=&quot;balancing_tp&quot;&gt;replication&lt;/span&gt;: { &lt;span class=&quot;balancing_tp&quot;&gt;read&lt;/span&gt;: [ { &lt;span class=&quot;balancing_tp&quot;&gt;host&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'replica-1'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;username&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'reader'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;password&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'***'&lt;/span&gt; }, { &lt;span class=&quot;balancing_tp&quot;&gt;host&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'replica-2'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;username&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'reader'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;password&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'***'&lt;/span&gt; } ], &lt;span class=&quot;balancing_tp&quot;&gt;write&lt;/span&gt;: { &lt;span class=&quot;balancing_tp&quot;&gt;host&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'master-db'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;username&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'writer'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;password&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'***'&lt;/span&gt; } }, &lt;span class=&quot;balancing_tp&quot;&gt;dialect&lt;/span&gt;: &lt;span class=&quot;balancing_st&quot;&gt;'postgres'&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;pool&lt;/span&gt;: { &lt;span class=&quot;balancing_tp&quot;&gt;max&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;30&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;min&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;balancing_tp&quot;&gt;idle&lt;/span&gt;: &lt;span class=&quot;balancing_nm&quot;&gt;10000&lt;/span&gt; } });&lt;/div&gt;
&lt;div class=&quot;balancing_warn&quot;&gt;&lt;b&gt;주의 &amp;mdash; 복제 지연(Replication Lag)&lt;/b&gt; &amp;mdash; Master에서 Replica로의 데이터 복제는 비동기로 이루어지므로 수 밀리초에서 수 초의 지연이 발생할 수 있습니다. 사용자가 게시글을 작성한 직후 목록을 조회하면 방금 작성한 글이 보이지 않는 문제가 생길 수 있습니다. 쓰기 직후 읽기(Read-after-Write) 시에는 강제로 Master에서 조회하도록 처리해야 합니다.&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;6&lt;/span&gt;캐싱 전략 &amp;mdash; DB 부하를 줄이는 가장 효과적인 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리 DB를 분산해도 동일한 데이터를 반복 조회하는 요청은 &lt;b&gt;캐시로 처리하는 것이 가장 효율적&lt;/b&gt;입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 적용 계층&lt;/h4&gt;
&lt;div class=&quot;balancing_diagram&quot;&gt;[클라이언트] --&amp;gt; [CDN 캐시] --&amp;gt; [애플리케이션 캐시] --&amp;gt; [DB 캐시] --&amp;gt; [DB] (정적 자원) (Redis / Local) (Query Cache)&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ASP.NET Core &amp;mdash; IDistributedCache 기반 Look-Aside 패턴&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;public class&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;ProductService&lt;/span&gt; { &lt;span class=&quot;balancing_kw&quot;&gt;private readonly&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;IDistributedCache&lt;/span&gt; _cache; &lt;span class=&quot;balancing_kw&quot;&gt;private readonly&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;ReadDbContext&lt;/span&gt; _db; &lt;span class=&quot;balancing_kw&quot;&gt;public async&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;Task&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;Product&lt;/span&gt;&amp;gt; &lt;span class=&quot;balancing_kw&quot;&gt;GetProduct&lt;/span&gt;(&lt;span class=&quot;balancing_tp&quot;&gt;long&lt;/span&gt; id) { &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; key = &lt;span class=&quot;balancing_st&quot;&gt;$&quot;product:{id}&quot;&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; cached = &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; _cache.&lt;span class=&quot;balancing_kw&quot;&gt;GetStringAsync&lt;/span&gt;(key); &lt;span class=&quot;balancing_kw&quot;&gt;if&lt;/span&gt; (cached != &lt;span class=&quot;balancing_kw&quot;&gt;null&lt;/span&gt;) &lt;span class=&quot;balancing_kw&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;JsonSerializer&lt;/span&gt;.&lt;span class=&quot;balancing_kw&quot;&gt;Deserialize&lt;/span&gt;&amp;lt;&lt;span class=&quot;balancing_tp&quot;&gt;Product&lt;/span&gt;&amp;gt;(cached); &lt;span class=&quot;balancing_kw&quot;&gt;var&lt;/span&gt; product = &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; _db.Products.&lt;span class=&quot;balancing_kw&quot;&gt;FindAsync&lt;/span&gt;(id); &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; _cache.&lt;span class=&quot;balancing_kw&quot;&gt;SetStringAsync&lt;/span&gt;(key, &lt;span class=&quot;balancing_tp&quot;&gt;JsonSerializer&lt;/span&gt;.&lt;span class=&quot;balancing_kw&quot;&gt;Serialize&lt;/span&gt;(product), &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;DistributedCacheEntryOptions&lt;/span&gt; { &lt;span class=&quot;balancing_tp&quot;&gt;AbsoluteExpirationRelativeToNow&lt;/span&gt; = &lt;span class=&quot;balancing_tp&quot;&gt;TimeSpan&lt;/span&gt;.&lt;span class=&quot;balancing_kw&quot;&gt;FromMinutes&lt;/span&gt;(&lt;span class=&quot;balancing_nm&quot;&gt;30&lt;/span&gt;) }); &lt;span class=&quot;balancing_kw&quot;&gt;return&lt;/span&gt; product; } }&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Node.js &amp;mdash; ioredis 기반 캐시 유틸리티&lt;/h4&gt;
&lt;div class=&quot;balancing_code&quot;&gt;&lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; Redis = &lt;span class=&quot;balancing_kw&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'ioredis'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; redis = &lt;span class=&quot;balancing_kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;balancing_tp&quot;&gt;Redis&lt;/span&gt;(&lt;span class=&quot;balancing_st&quot;&gt;'redis://redis-server:6379'&lt;/span&gt;); &lt;span class=&quot;balancing_kw&quot;&gt;async function&lt;/span&gt; &lt;span class=&quot;balancing_kw&quot;&gt;getProduct&lt;/span&gt;(id) { &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; key = &lt;span class=&quot;balancing_st&quot;&gt;`product:${id}`&lt;/span&gt;; &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; cached = &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; redis.&lt;span class=&quot;balancing_kw&quot;&gt;get&lt;/span&gt;(key); &lt;span class=&quot;balancing_kw&quot;&gt;if&lt;/span&gt; (cached) &lt;span class=&quot;balancing_kw&quot;&gt;return&lt;/span&gt; JSON.&lt;span class=&quot;balancing_kw&quot;&gt;parse&lt;/span&gt;(cached); &lt;span class=&quot;balancing_kw&quot;&gt;const&lt;/span&gt; product = &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; db.&lt;span class=&quot;balancing_kw&quot;&gt;query&lt;/span&gt;( &lt;span class=&quot;balancing_st&quot;&gt;'SELECT * FROM products WHERE id = $1'&lt;/span&gt;, [id] ); &lt;span class=&quot;balancing_kw&quot;&gt;await&lt;/span&gt; redis.&lt;span class=&quot;balancing_kw&quot;&gt;setex&lt;/span&gt;(key, &lt;span class=&quot;balancing_nm&quot;&gt;1800&lt;/span&gt;, JSON.&lt;span class=&quot;balancing_kw&quot;&gt;stringify&lt;/span&gt;(product.rows[&lt;span class=&quot;balancing_nm&quot;&gt;0&lt;/span&gt;]) ); &lt;span class=&quot;balancing_kw&quot;&gt;return&lt;/span&gt; product.rows[&lt;span class=&quot;balancing_nm&quot;&gt;0&lt;/span&gt;]; }&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 무효화(Invalidation) 전략 비교&lt;/h4&gt;
&lt;div class=&quot;balancing_tbl&quot;&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;장점&lt;/th&gt;
&lt;th&gt;단점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;TTL 기반&lt;/b&gt;&lt;/td&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;b&gt;Write-Through&lt;/b&gt;&lt;/td&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;b&gt;Write-Behind&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;캐시에 먼저 쓰고 일정 주기로 DB에 반영&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;b&gt;이벤트 기반&lt;/b&gt;&lt;/td&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;balancing_badge&quot;&gt;7&lt;/span&gt;대용량 트래픽 대응 &amp;mdash; 실무 체크리스트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 서비스에서 대규모 트래픽에 대비할 때 점검해야 할 항목을 계층별로 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;WAS 계층&lt;/h4&gt;
&lt;ul class=&quot;balancing_checklist&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로드밸런서 구성 (L4/L7 선택, IIS ARR 또는 Nginx)&lt;/li&gt;
&lt;li&gt;Auto Scaling 정책 수립 (CPU, 메모리, 요청 수 기준)&lt;/li&gt;
&lt;li&gt;Stateless 설계 (세션 외부 저장소 또는 JWT)&lt;/li&gt;
&lt;li&gt;서킷 브레이커(Circuit Breaker) 적용 &amp;mdash; 외부 서비스 장애 전파 방지&lt;/li&gt;
&lt;li&gt;Rate Limiting / Throttling &amp;mdash; 비정상 트래픽 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;DB 계층&lt;/h4&gt;
&lt;ul class=&quot;balancing_checklist&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Connection Pool 적정 사이즈 산정&lt;/li&gt;
&lt;li&gt;읽기/쓰기 분리 (Read Replica)&lt;/li&gt;
&lt;li&gt;쿼리 최적화 및 인덱스 점검&lt;/li&gt;
&lt;li&gt;Slow Query 모니터링&lt;/li&gt;
&lt;li&gt;필요 시 샤딩(Sharding) 검토&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 계층&lt;/h4&gt;
&lt;ul class=&quot;balancing_checklist&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Redis/Memcached 클러스터 구성&lt;/li&gt;
&lt;li&gt;캐시 히트율 모니터링 (목표: 80% 이상)&lt;/li&gt;
&lt;li&gt;캐시 스탬피드(Cache Stampede) 방지 &amp;mdash; 동시 만료 시 DB 폭주 대비&lt;/li&gt;
&lt;li&gt;Hot Key 분산 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인프라 / 모니터링&lt;/h4&gt;
&lt;ul class=&quot;balancing_checklist&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CDN 적용 (정적 자원)&lt;/li&gt;
&lt;li&gt;메시지 큐(Kafka, RabbitMQ) 도입 &amp;mdash; 비동기 처리로 피크 부하 완화&lt;/li&gt;
&lt;li&gt;APM 도구(Datadog, Grafana, Pinpoint 등) 연동&lt;/li&gt;
&lt;li&gt;부하 테스트(nGrinder, k6, JMeter) 정기 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div class=&quot;balancing_ref&quot;&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;&lt;b&gt;Microsoft &amp;mdash; IIS Application Request Routing&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/iis/extensions/planning-for-arr/application-request-routing-version-2-overview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/iis/extensions/planning-for-arr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft &amp;mdash; ASP.NET Core 분산 캐싱&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/aspnet/core/performance/caching/distributed&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/aspnet/core/performance/caching/distributed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft &amp;mdash; ASP.NET Core Data Protection 키 저장소&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft &amp;mdash; ASP.NET Core Health Checks&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft &amp;mdash; SqlConnection 커넥션 풀링&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Nginx &amp;mdash; HTTP Load Balancing&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Node.js &amp;mdash; Cluster 모듈 공식 문서&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://nodejs.org/api/cluster.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nodejs.org/api/cluster.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PM2 &amp;mdash; Cluster Mode 공식 문서&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://pm2.keymetrics.io/docs/usage/cluster-mode/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pm2.keymetrics.io/docs/usage/cluster-mode/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HikariCP &amp;mdash; GitHub (Connection Pool)&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/brettwooldridge/HikariCP&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/brettwooldridge/HikariCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;node-postgres (pg) &amp;mdash; Connection Pool&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://node-postgres.com/features/pooling&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://node-postgres.com/features/pooling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Sequelize &amp;mdash; Read Replication&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://sequelize.org/docs/v6/other-topics/read-replication/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://sequelize.org/docs/v6/other-topics/read-replication/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Redis &amp;mdash; 공식 문서&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://redis.io/docs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://redis.io/docs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런싱과 DB 분산 전략은 서비스가 성장할수록 반드시 마주하게 되는 과제입니다. 처음부터 완벽한 아키텍처를 설계할 필요는 없지만, 각 기술이 &lt;b&gt;어떤 문제를 해결하는지&lt;/b&gt;, 그리고 &lt;b&gt;어떤 트레이드오프가 있는지&lt;/b&gt; 이해하고 있으면 장애 상황에서 훨씬 빠르게 대응할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;balancing_summary&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;핵심 정리!&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;WAS는 Stateless하게&lt;/b&gt; 설계하고 로드밸런서로 수평 확장합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DB는 커넥션 풀 관리와 읽기/쓰기 분리&lt;/b&gt;로 병목을 줄입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐시를 적극 활용&lt;/b&gt;하여 불필요한 DB 접근을 줄입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은 규모의 서비스라도 이런 구조를 머릿속에 그려두시면, 나중에 트래픽이 증가했을 때 당황하지 않고 단계적으로 확장할 수 있을 것입니다.&lt;/p&gt;
&lt;div class=&quot;balancing_tags&quot;&gt;&lt;span&gt;#로드밸런싱&lt;/span&gt; &lt;span&gt;#LoadBalancing&lt;/span&gt; &lt;span&gt;#DB분산처리&lt;/span&gt; &lt;span&gt;#ConnectionPool&lt;/span&gt; &lt;span&gt;#ReadReplica&lt;/span&gt; &lt;span&gt;#캐싱전략&lt;/span&gt; &lt;span&gt;#대용량트래픽&lt;/span&gt; &lt;span&gt;#서버아키텍처&lt;/span&gt; &lt;span&gt;#ASPNETCore&lt;/span&gt; &lt;span&gt;#NodeJS&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>ASP.NET Core 분산 세션</category>
      <category>connection pool</category>
      <category>DB 커넥션 풀</category>
      <category>IIS ARR 서버팜</category>
      <category>load balancing</category>
      <category>Node.js 클러스터</category>
      <category>read replica</category>
      <category>Redis 캐싱 전략</category>
      <category>대용량 트래픽 처리</category>
      <category>로드밸런싱</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/580</guid>
      <comments>https://odinbox.tistory.com/580#entry580comment</comments>
      <pubDate>Sun, 12 Apr 2026 00:04:57 +0900</pubDate>
    </item>
    <item>
      <title>Claude Code 소스 유출 사건 총정리, 유출 경위, 타임라인, 취약점, 그리고 개발자가 반드시 봐야 할 핵심</title>
      <link>https://odinbox.tistory.com/579</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oWyG5/dJMcaflPuPV/yKbaevNG5nL6iiWvol4Jwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oWyG5/dJMcaflPuPV/yKbaevNG5nL6iiWvol4Jwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oWyG5/dJMcaflPuPV/yKbaevNG5nL6iiWvol4Jwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoWyG5%2FdJMcaflPuPV%2FyKbaevNG5nL6iiWvol4Jwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;style&gt;
  .caludecodehack_wrap{
    --caludecodehack_bg:#f7f9fc;
    --caludecodehack_card:#ffffff;
    --caludecodehack_line:#e5eaf2;
    --caludecodehack_line2:#d9e2ef;
    --caludecodehack_text:#18212f;
    --caludecodehack_sub:#556070;
    --caludecodehack_muted:#6b7788;
    --caludecodehack_point:#1f5fae;
    --caludecodehack_point_dark:#123d73;
    --caludecodehack_point_soft:#eef5ff;
    --caludecodehack_dark:#0b1220;
    --caludecodehack_dark2:#111a2b;
    --caludecodehack_warn:#a03a12;
    --caludecodehack_warn_soft:#fff5ef;
    --caludecodehack_ok:#0f6b46;
    --caludecodehack_ok_soft:#eefbf4;
    --caludecodehack_shadow:0 10px 30px rgba(15,23,42,0.06);
    --caludecodehack_radius:22px;
    max-width:1080px;
    margin:0 auto;
    padding:16px 20px 80px;
    color:var(--caludecodehack_text);
    font-family:&quot;Pretendard&quot;,&quot;Noto Sans KR&quot;,&quot;Malgun Gothic&quot;,sans-serif;
    line-height:1.82;
    word-break:keep-all;
  }
  .caludecodehack_wrap *{
    box-sizing:border-box;
  }
  .caludecodehack_wrap a{
    color:var(--caludecodehack_point);
    text-decoration:none;
  }

  .caludecodehack_doc_header{
    background:linear-gradient(180deg,#fbfdff 0%, #f3f7fc 100%);
    border:1px solid var(--caludecodehack_line);
    border-radius:28px;
    padding:30px 28px;
    box-shadow:var(--caludecodehack_shadow);
    margin:0 0 22px;
  }
  .caludecodehack_doc_kicker{
    display:inline-flex;
    align-items:center;
    gap:8px;
    border:1px solid var(--caludecodehack_line2);
    background:#fff;
    color:var(--caludecodehack_point_dark);
    border-radius:999px;
    padding:8px 12px;
    font-size:13px;
    font-weight:800;
    margin-bottom:14px;
  }
  .caludecodehack_doc_title{
    margin:0 0 14px;
    font-size:clamp(30px,4vw,42px);
    line-height:1.3;
    font-weight:900;
    letter-spacing:-0.03em;
    color:#0f172a;
  }
  .caludecodehack_doc_desc{
    margin:0 0 18px;
    font-size:17px;
    color:var(--caludecodehack_sub);
  }
  .caludecodehack_doc_meta{
    display:grid;
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:12px;
    margin-top:16px;
  }
  .caludecodehack_doc_meta_item{
    border:1px solid var(--caludecodehack_line);
    background:#fff;
    border-radius:18px;
    padding:14px 14px;
  }
  .caludecodehack_doc_meta_item strong{
    display:block;
    margin-bottom:6px;
    font-size:12px;
    font-weight:900;
    color:var(--caludecodehack_muted);
    text-transform:uppercase;
    letter-spacing:.04em;
  }
  .caludecodehack_doc_meta_item span{
    display:block;
    font-size:15px;
    font-weight:800;
    color:#111827;
    line-height:1.5;
  }

  .caludecodehack_toc{
    background:var(--caludecodehack_card);
    border:1px solid var(--caludecodehack_line);
    border-radius:var(--caludecodehack_radius);
    box-shadow:var(--caludecodehack_shadow);
    padding:24px 24px;
    margin:0 0 22px;
  }
  .caludecodehack_toc h2{
    margin:0 0 12px;
    font-size:22px;
    font-weight:900;
    color:#0f172a;
  }
  .caludecodehack_toc ul{
    list-style:none;
    margin:0;
    padding:0;
    display:grid;
    gap:9px;
  }
  .caludecodehack_toc li{
    margin:0;
    padding:0;
  }
  .caludecodehack_toc a{
    display:block;
    padding:10px 12px;
    border-radius:12px;
    color:var(--caludecodehack_point_dark);
    font-weight:800;
    background:#f8fbff;
    border:1px solid #edf3fb;
  }

  .caludecodehack_section{
    background:var(--caludecodehack_card);
    border:1px solid var(--caludecodehack_line);
    border-radius:var(--caludecodehack_radius);
    box-shadow:var(--caludecodehack_shadow);
    padding:30px 24px;
    margin:0 0 22px;
  }
  .caludecodehack_section h2{
    margin:0 0 18px;
    padding-bottom:12px;
    border-bottom:2px solid #edf2f7;
    font-size:30px;
    line-height:1.35;
    font-weight:900;
    letter-spacing:-0.02em;
    color:#0f172a;
  }
  .caludecodehack_section h3{
    margin:28px 0 12px;
    font-size:23px;
    line-height:1.45;
    font-weight:900;
    letter-spacing:-0.02em;
    color:#111827;
  }
  .caludecodehack_section h4{
    margin:22px 0 10px;
    font-size:18px;
    line-height:1.5;
    font-weight:800;
    color:#111827;
  }
  .caludecodehack_section p{
    margin:0 0 16px;
    font-size:17px;
    color:var(--caludecodehack_text);
  }
  .caludecodehack_lead{
    font-size:18px;
    font-weight:700;
    color:#233247;
  }

  .caludecodehack_note,
  .caludecodehack_warn,
  .caludecodehack_ok{
    border-radius:18px;
    padding:18px 18px;
    margin:18px 0;
    border:1px solid transparent;
  }
  .caludecodehack_note{
    background:var(--caludecodehack_point_soft);
    border-color:#d8e7ff;
  }
  .caludecodehack_warn{
    background:var(--caludecodehack_warn_soft);
    border-color:#f3d1c2;
  }
  .caludecodehack_ok{
    background:var(--caludecodehack_ok_soft);
    border-color:#ccead9;
  }

  .caludecodehack_quote{
    margin:18px 0;
    padding:18px 20px;
    background:#f8fbff;
    border:1px solid #e5efff;
    border-left:4px solid var(--caludecodehack_point);
    border-radius:0 16px 16px 0;
    font-size:18px;
    font-weight:800;
    color:#10233f;
  }

  .caludecodehack_list{
    list-style:none;
    margin:16px 0;
    padding:0;
  }
  .caludecodehack_list li{
    position:relative;
    padding-left:18px;
    margin:0 0 12px;
    color:var(--caludecodehack_text);
  }
  .caludecodehack_list li::before{
    content:&quot;&quot;;
    position:absolute;
    left:0;
    top:12px;
    width:7px;
    height:7px;
    border-radius:50%;
    background:var(--caludecodehack_point);
  }
  .caludecodehack_label{
    font-weight:900;
    color:#0f172a;
  }

  .caludecodehack_grid{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:16px;
    margin:18px 0;
  }
  .caludecodehack_card_mini{
    border:1px solid var(--caludecodehack_line);
    background:#fbfcfe;
    border-radius:18px;
    padding:18px;
  }
  .caludecodehack_card_mini h4{
    margin:0 0 8px;
    font-size:18px;
    font-weight:900;
  }
  .caludecodehack_card_mini p{
    margin:0;
    font-size:15px;
    color:var(--caludecodehack_sub);
  }

  .caludecodehack_table{
    width:100%;
    border-collapse:collapse;
    margin:18px 0;
    font-size:15px;
  }
  .caludecodehack_table th,
  .caludecodehack_table td{
    border:1px solid var(--caludecodehack_line);
    padding:14px 12px;
    text-align:left;
    vertical-align:top;
  }
  .caludecodehack_table th{
    background:#f8fbff;
    font-weight:900;
    color:#111827;
  }

  .caludecodehack_timeline{
    position:relative;
    margin:16px 0 0;
    padding-left:22px;
    border-left:2px solid #d9e4f3;
  }
  .caludecodehack_timeline_item{
    position:relative;
    padding:0 0 20px 14px;
  }
  .caludecodehack_timeline_item::before{
    content:&quot;&quot;;
    position:absolute;
    left:-29px;
    top:8px;
    width:12px;
    height:12px;
    border-radius:50%;
    background:var(--caludecodehack_point);
    box-shadow:0 0 0 4px #edf4ff;
  }
  .caludecodehack_time{
    display:inline-block;
    margin-bottom:8px;
    padding:6px 10px;
    background:#eef5ff;
    color:var(--caludecodehack_point_dark);
    border-radius:999px;
    font-size:13px;
    font-weight:900;
  }

  .caludecodehack_codewrap{
    margin:16px 0 18px;
    border:1px solid #1f2b42;
    border-radius:18px;
    overflow:hidden;
    background:var(--caludecodehack_dark);
    box-shadow:inset 0 1px 0 rgba(255,255,255,0.03);
  }
  .caludecodehack_codehead{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    padding:10px 14px;
    background:var(--caludecodehack_dark2);
    border-bottom:1px solid rgba(255,255,255,0.06);
  }
  .caludecodehack_codehead strong{
    font-size:13px;
    font-weight:900;
    color:#d7e3ff;
    letter-spacing:.02em;
  }
  .caludecodehack_codehead span{
    font-size:12px;
    color:#8ea3c7;
  }
  .caludecodehack_codeblock{
    margin:0;
    padding:18px 18px 20px;
    overflow:auto;
    font-size:15px;
    line-height:1.75;
    color:#f4f7ff;
    font-family:Consolas, &quot;SFMono-Regular&quot;, Menlo, Monaco, &quot;Liberation Mono&quot;, monospace;
    white-space:pre;
  }

  .caludecodehack_faq{
    display:grid;
    gap:14px;
    margin-top:18px;
  }
  .caludecodehack_faq details{
    border:1px solid var(--caludecodehack_line);
    background:#fff;
    border-radius:18px;
    padding:16px 18px;
  }
  .caludecodehack_faq summary{
    cursor:pointer;
    font-weight:900;
    color:#111827;
  }
  .caludecodehack_faq p{
    margin:12px 0 0;
    color:var(--caludecodehack_sub);
  }

  .caludecodehack_tags{
    display:flex;
    flex-wrap:wrap;
    gap:10px;
    margin-top:18px;
  }
  .caludecodehack_tags span{
    display:inline-block;
    padding:9px 12px;
    border-radius:999px;
    border:1px solid var(--caludecodehack_line);
    background:#fff;
    font-size:13px;
    font-weight:800;
    color:#22324a;
  }

  .caludecodehack_refs{
    list-style:none;
    margin:0;
    padding:0;
  }
  .caludecodehack_refs li{
    margin:0 0 10px;
    padding-left:16px;
    position:relative;
    color:var(--caludecodehack_sub);
    font-size:15px;
  }
  .caludecodehack_refs li::before{
    content:&quot;&quot;;
    position:absolute;
    left:0;
    top:11px;
    width:6px;
    height:6px;
    border-radius:50%;
    background:var(--caludecodehack_point);
  }

  .caludecodehack_cta{
    background:linear-gradient(180deg,#103c73 0%, #1b56a0 100%);
    color:#fff;
    border-radius:24px;
    padding:30px 24px;
    box-shadow:var(--caludecodehack_shadow);
    margin-top:28px;
  }
  .caludecodehack_cta h2{
    margin:0 0 14px;
    font-size:28px;
    line-height:1.4;
    font-weight:900;
  }
  .caludecodehack_cta p{
    margin:0 0 10px;
    color:rgba(255,255,255,0.96);
  }

  @media (max-width:920px){
    .caludecodehack_doc_meta,
    .caludecodehack_grid{
      grid-template-columns:1fr;
    }
    .caludecodehack_wrap{
      padding:14px 14px 60px;
    }
    .caludecodehack_doc_header,
    .caludecodehack_toc,
    .caludecodehack_section,
    .caludecodehack_cta{
      padding:22px 18px;
      border-radius:20px;
    }
    .caludecodehack_doc_title{
      font-size:28px;
    }
    .caludecodehack_section h2{
      font-size:24px;
    }
    .caludecodehack_section h3{
      font-size:20px;
    }
    .caludecodehack_codeblock{
      font-size:14px;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;caludecodehack_wrap&quot;&gt;
&lt;section class=&quot;caludecodehack_doc_header&quot;&gt;
&lt;div class=&quot;caludecodehack_doc_kicker&quot;&gt;Security Analysis &amp;middot; Claude Code Leak &amp;middot; Developer Notes&lt;/div&gt;
&lt;h1 class=&quot;caludecodehack_doc_title&quot;&gt;Claude Code 소스 유출 사건 총정리 : 유출 경위, 타임라인, 취약점, 그리고 개발자가 반드시 봐야 할 핵심&lt;/h1&gt;
&lt;p class=&quot;caludecodehack_doc_desc&quot; data-ke-size=&quot;size16&quot;&gt;이번 Claude Code 소스 유출 사건은 단순한 코드 공개 이슈가 아닙니다. AI 코딩 도구의 배포 구조, 권한 제어, 샌드박스 모델, 설정 파일 신뢰 경계, DevSecOps 수준의 릴리즈 관리까지 한 번에 드러난 사건이었습니다. 이 글에서는 사건의 흐름부터 기술적 의미, 실무자가 당장 점검해야 할 포인트까지 개발자 관점으로 정리합니다.&lt;/p&gt;
&lt;div class=&quot;caludecodehack_doc_meta&quot;&gt;
&lt;div class=&quot;caludecodehack_doc_meta_item&quot;&gt;&lt;b&gt;Topic&lt;/b&gt; &lt;span&gt;Claude Code source leak&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;caludecodehack_doc_meta_item&quot;&gt;&lt;b&gt;Focus&lt;/b&gt; &lt;span&gt;보안 구조 &amp;middot; 에이전트 실행 &amp;middot; 공급망 리스크&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;caludecodehack_doc_meta_item&quot;&gt;&lt;b&gt;Audience&lt;/b&gt; &lt;span&gt;개발자 &amp;middot; 보안 담당자 &amp;middot; DevSecOps 실무자&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;caludecodehack_toc&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;&lt;a href=&quot;#caludecodehack_sec1&quot;&gt;1. Claude Code 유출 사건이 왜 큰 문제였나&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec2&quot;&gt;2. 유출 경위와 주요 타임라인&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec3&quot;&gt;3. 유출된 것과 유출되지 않은 것&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec4&quot;&gt;4. Claude Code 내부 구조와 기술 포인트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec4a&quot;&gt;4-1. 유출된 소스에서 드러난 핵심 코드 패턴&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec5&quot;&gt;5. 취약점, 보안 결함, 실제 위험성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec6&quot;&gt;6. 개발자와 조직이 지금 점검해야 할 대응책&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec7&quot;&gt;7. 마무리 : 이번 사건이 남긴 진짜 교훈&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec8&quot;&gt;8. 자주 묻는 질문 Q&amp;amp;A&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#caludecodehack_sec9&quot;&gt;9. 참고 자료&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec1&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Claude Code 유출 사건이 왜 큰 문제였나&lt;/h2&gt;
&lt;p class=&quot;caludecodehack_lead&quot; data-ke-size=&quot;size16&quot;&gt;결론부터 말하면, 이번 사건은 단순히 코드가 노출됐다는 수준을 넘어서, AI 에이전트형 개발 도구가 실제로 어떤 방식으로 동작하는지 운영 구조가 바깥으로 드러났다는 점에서 매우 민감했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 이번 사건은 모델 가중치나 고객 데이터가 통째로 빠져나간 형태와는 다르게, Claude Code의 에이전트 런타임 구조, 권한 정책, 도구 실행 흐름, 샌드박스 설계, 설정 파일 처리 방식 같은 핵심 구현 디테일이 외부 분석 대상이 되었다는 점이 중요합니다.&lt;/p&gt;
&lt;div class=&quot;caludecodehack_note&quot;&gt;&lt;b&gt;핵심 요약&lt;/b&gt;&lt;br /&gt;이번 유출은 모델 유출이라기보다 AI 코딩 도구 운영 구조 노출에 가깝습니다. 그래서 공격자 입장에서는 취약점을 더 빨리 찾을 수 있고, 개발자 입장에서는 제품의 신뢰 경계가 어디서 무너질 수 있는지 더 선명하게 보이게 됩니다.&lt;/div&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;사건의 본질 : &lt;/span&gt;코드 몇 줄이 새어나간 문제가 아니라 배포 거버넌스 실패 문제였습니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;보안적 의미 : &lt;/span&gt;권한 모델과 샌드박스 설계의 약한 부분을 외부가 빠르게 검토할 수 있게 됐습니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;개발자 관점 : &lt;/span&gt;소스맵, 디버그 파일, 패키징 파일 경계가 얼마나 중요한지 다시 보여준 사례였습니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;콘텐츠 가치 : &lt;/span&gt;AI 보안, DevSecOps, 공급망 보안이라는 검색 키워드를 동시에 잡을 수 있는 주제입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;caludecodehack_quote&quot;&gt;이번 사건의 진짜 무게는 AI가 아니라 배포 과정에서 터졌다는 데 있습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec2&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 유출 경위와 주요 타임라인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개된 분석들을 보면, Claude Code 배포 과정에서 디버깅용 source map 파일이 공개 패키지에 함께 포함되면서 내부 TypeScript 코드가 대규모로 복원 가능한 상태가 된 것이 사건의 출발점으로 정리됩니다.&lt;/p&gt;
&lt;div class=&quot;caludecodehack_warn&quot;&gt;&lt;b&gt;중요 포인트&lt;/b&gt;&lt;br /&gt;이번 이슈는 흔히 떠올리는 외부 침입형 해킹과는 성격이 다릅니다. 공개되면 안 되는 배포 아티팩트가 릴리즈 과정에서 노출된 사고에 더 가깝습니다.&lt;/div&gt;
&lt;div class=&quot;caludecodehack_timeline&quot;&gt;
&lt;div class=&quot;caludecodehack_timeline_item&quot;&gt;
&lt;div class=&quot;caludecodehack_time&quot;&gt;2026-03-31&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;초기 유출 정황 : &lt;/span&gt;업데이트 배포물에 source map 파일이 포함되며 내부 코드 복원이 가능해졌다는 분석이 확산되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;caludecodehack_timeline_item&quot;&gt;
&lt;div class=&quot;caludecodehack_time&quot;&gt;2026-03-31&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;커뮤니티 반응 : &lt;/span&gt;개발자와 연구자들이 온라인에서 유출 정황과 구조 분석을 빠르게 공유하기 시작했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;caludecodehack_timeline_item&quot;&gt;
&lt;div class=&quot;caludecodehack_time&quot;&gt;2026-04-01&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;삭제 요청 확대 : &lt;/span&gt;복제 저장소에 대한 대량 삭제 요청과 함께 과잉 대응 논란도 이어졌습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;caludecodehack_timeline_item&quot;&gt;
&lt;div class=&quot;caludecodehack_time&quot;&gt;2026-04-01 ~ 2026-04-02&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;취약점 재조명 : &lt;/span&gt;deny rule 우회, 설정 기반 신뢰 경계 문제 등 기존 보안 이슈가 다시 주목받기 시작했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;caludecodehack_timeline_item&quot;&gt;
&lt;div class=&quot;caludecodehack_time&quot;&gt;이후&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;2차 피해 우려 : &lt;/span&gt;유출 소스를 사칭한 저장소나 설치 파일이 악성코드 유포에 악용될 수 있다는 경고가 뒤따랐습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec3&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 유출된 것과 유출되지 않은 것&lt;/h2&gt;
&lt;div class=&quot;caludecodehack_grid&quot;&gt;
&lt;div class=&quot;caludecodehack_card_mini&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;유출된 것&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트 런타임 구조, 권한 처리 흐름, 도구 호출 방식, 샌드박스 설계, 훅 및 설정 파일 관련 구현 정보&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;caludecodehack_card_mini&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;유출되지 않은 것&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 가중치 전체, 고객 데이터 전체, 전형적인 대규모 계정 탈취형 정보 유출로 보기는 어려운 요소들&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 점이 중요한 이유는 단순한 코드 노출과 제품 내부 구조 노출이 완전히 다른 파장을 만들기 때문입니다. 전자는 저작권이나 경쟁 이슈에 그칠 수 있지만, 후자는 보안 경계와 우회 포인트를 함께 노출시킵니다.&lt;/p&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;핵심 구분 : &lt;/span&gt;모델이 털렸다기보다 제품이 어떻게 움직이는지가 드러났다는 쪽에 가깝습니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;실제 위험 : &lt;/span&gt;공격자는 권한 정책과 샌드박스의 빈틈을 더 효율적으로 찾을 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;산업적 함의 : &lt;/span&gt;AI 에이전트 도구의 경쟁 우위와 내부 설계 철학이 함께 노출될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec4&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Claude Code 내부 구조와 기술 포인트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개된 분석 흐름을 종합하면 Claude Code는 단순한 채팅형 AI가 아니라, 터미널 환경에서 파일을 읽고, 수정하고, Bash 명령을 실행하고, 외부 도구와 연계하는 에이전트 런타임에 가깝습니다.&lt;/p&gt;
&lt;table class=&quot;caludecodehack_table&quot; 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;개발자 관점 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;도구 실행 계층&lt;/td&gt;
&lt;td&gt;파일 수정, Bash, WebFetch, MCP 연동 등 실제 행동 수행&lt;/td&gt;
&lt;td&gt;LLM이 단순 답변이 아니라 작업을 실행하는 핵심 계층&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;권한 모델&lt;/td&gt;
&lt;td&gt;deny, ask, allow 규칙과 모드 조합으로 위험 행동 제어&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;OS 수준 격리를 통해 파일과 네트워크 접근 제한&lt;/td&gt;
&lt;td&gt;권한 규칙이 실패해도 피해를 줄이는 마지막 방어선&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;caludecodehack_note&quot;&gt;&lt;b&gt;개발자 해석&lt;/b&gt;&lt;br /&gt;에이전트형 AI 도구의 위험은 모델 성능보다 무엇을 할 수 있는지, 어떤 조건에서 허용되는지, 막히지 않으면 어디까지 실행되는지에 달려 있습니다.&lt;/div&gt;
&lt;div class=&quot;caludecodehack_quote&quot;&gt;에이전트형 AI 제품의 보안은 답변 품질이 아니라 경계 조건 설계로 결정됩니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec4a&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4-1. 유출된 소스에서 드러난 핵심 코드 패턴&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예시는 유출 원문을 그대로 옮긴 것이 아니라, 공개 분석에서 공통적으로 확인된 구조를 바탕으로 재구성한 축약 예시입니다. 실제로 어떤 부분이 핵심이었는지 개발자가 빠르게 이해할 수 있도록 정리했습니다.&lt;/p&gt;
&lt;div class=&quot;caludecodehack_note&quot;&gt;&lt;b&gt;왜 이 섹션이 중요한가&lt;/b&gt;&lt;br /&gt;단순히 코드가 유출됐다고만 쓰면 글의 전문성이 약해집니다. 반대로 에이전트 루프, 도구 등록, 권한 판정, 보안 경계 같은 구조를 코드 패턴으로 보여주면 개발자 독자의 체류시간과 신뢰도가 더 높아집니다.&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시 1. 에이전트의 심장부 역할을 하는 반복 루프&lt;/h3&gt;
&lt;div class=&quot;caludecodehack_codewrap&quot;&gt;
&lt;div class=&quot;caludecodehack_codehead&quot;&gt;&lt;b&gt;Agent Loop Example&lt;/b&gt; &lt;span&gt;reconstructed for explanation&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;caludecodehack_codeblock cs&quot;&gt;&lt;code&gt;while (true) {
  const modelEvents = callModel(systemPrompt, messages, toolContext)

  for await (const event of modelEvents) {
    if (event.type === 'assistant_message') appendMessage(event)
    if (event.type === 'tool_call') queueTool(event)
  }

  if (queuedTools.length &amp;gt; 0) {
    const toolResults = await runTools(queuedTools)
    messages.push(...toolResults)
    continue
  }

  break
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;설명 : &lt;/span&gt;사용자 요청 &amp;rarr; 모델 응답 &amp;rarr; 도구 호출 &amp;rarr; 결과 반영 &amp;rarr; 다음 턴 반복이라는 에이전트형 실행 구조를 보여줍니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;핵심 포인트 : &lt;/span&gt;이 구조 때문에 Claude Code는 단순 채팅이 아니라 실제로 파일을 고치고 명령을 실행하는 작업형 도구가 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시 2. 도구를 등록하고 기능 플래그로 제어하는 패턴&lt;/h3&gt;
&lt;div class=&quot;caludecodehack_codewrap&quot;&gt;
&lt;div class=&quot;caludecodehack_codehead&quot;&gt;&lt;b&gt;Tool Registration Example&lt;/b&gt; &lt;span&gt;feature flag pattern&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;caludecodehack_codeblock javascript&quot;&gt;&lt;code&gt;const WebBrowserTool =
  feature('WEB_BROWSER_TOOL')
    ? require('./tools/WebBrowserTool').WebBrowserTool
    : null

const tools = [
  ReadTool,
  EditTool,
  BashTool,
  ...(isToolSearchEnabledOptimistic() ? [ToolSearchTool] : [])
]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;설명 : &lt;/span&gt;도구 자체를 켜고 끄는 구조와, 필요 시에만 도구를 등록하거나 지연 로딩하는 패턴이 보입니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;핵심 포인트 : &lt;/span&gt;이런 구조는 성능 최적화와 내부 기능 숨김에 유리하지만, source map 노출 시 어떤 도구가 실제 제품에 들어가는지도 그대로 드러날 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시 3. 권한 모델과 샌드박스가 분리된 구조&lt;/h3&gt;
&lt;div class=&quot;caludecodehack_codewrap&quot;&gt;
&lt;div class=&quot;caludecodehack_codehead&quot;&gt;&lt;b&gt;Permission Decision Example&lt;/b&gt; &lt;span&gt;policy + sandbox separation&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;caludecodehack_codeblock reasonml&quot;&gt;&lt;code&gt;function decidePermission(toolCall, rules) {
  if (matchesDeny(toolCall, rules.deny)) return 'deny'
  if (matchesAllow(toolCall, rules.allow)) return 'allow'
  return 'ask'
}

const result = decidePermission(bashCall, permissionRules)

if (result === 'allow') {
  return runInSandbox(bashCall, sandboxPolicy)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;설명 : &lt;/span&gt;권한 판정과 실제 OS 수준 샌드박스 실행이 다른 층으로 나뉘는 전형적인 구조입니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;핵심 포인트 : &lt;/span&gt;정책이 한번 틀어져도 샌드박스가 막아줄 수 있어야 하고, 반대로 샌드박스가 없으면 권한 규칙 하나가 곧 전체 위험이 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시 4. 이번 논란과 직접 연결된 deny rule 우회 구조&lt;/h3&gt;
&lt;div class=&quot;caludecodehack_codewrap&quot;&gt;
&lt;div class=&quot;caludecodehack_codehead&quot;&gt;&lt;b&gt;Bash Guard Example&lt;/b&gt; &lt;span&gt;threshold-based security path&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;caludecodehack_codeblock actionscript&quot;&gt;&lt;code&gt;const MAX_SUBCOMMANDS_FOR_SECURITY_CHECK = 50

function evaluateBash(command, rules) {
  const subcommands = splitCompoundCommand(command)

  if (subcommands.length &amp;gt; MAX_SUBCOMMANDS_FOR_SECURITY_CHECK) {
    return { decision: 'ask', reason: 'too_many_subcommands' }
  }

  for (const item of subcommands) {
    if (matchesDeny(item, rules.deny)) {
      return { decision: 'deny' }
    }
  }

  return { decision: 'allow' }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;설명 : &lt;/span&gt;길이가 긴 복합 명령에서 보안 검사를 단순화하면 deny 규칙이 기대만큼 강하게 작동하지 않을 수 있다는 문제를 대준 예시입니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;핵심 포인트 : &lt;/span&gt;AI 에이전트는 사람이 직접 타이핑하지 않을 정도로 긴 명령 체인도 쉽게 생성하므로, 이런 임계치 기반 예외 처리는 위험해질 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;caludecodehack_warn&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;br /&gt;위 코드는 유출 원문을 그대로 복제한 것이 아니라, 공개적으로 알려진 구조를 이해하기 쉽게 블로그용으로 재구성한 축약 예시입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec5&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 취약점, 보안 결함, 실제 위험성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사건 이후 특히 많이 언급된 부분은 deny rule 우회 가능성, 파서 불일치, 그리고 설정 기반 신뢰 경계 문제였습니다. 공개 분석을 보면 단순 버그 한 개가 아니라, 에이전트형 AI 도구에서 성능 최적화와 보안 정책이 충돌할 때 어떤 식으로 위험이 생기는지가 그대로 드러났습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-1. deny rule 우회 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개 분석에 따르면, 서브커맨드가 지나치게 길어질 경우 보안 검사를 단순화하는 경로가 존재할 수 있고, 이때 deny 규칙이 기대만큼 강하게 작동하지 않는 구조가 논란이 되었습니다.&lt;/p&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;문제의 본질 : &lt;/span&gt;성능 최적화를 위해 만든 제한이 보안 정책을 밀어낸 구조적 문제&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;왜 위험한가 : &lt;/span&gt;AI 에이전트는 사람보다 훨씬 긴 명령 체인을 자연스럽게 생성할 수 있음&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;실무 교훈 : &lt;/span&gt;분석이 어려운 경우 기본 동작은 ask보다 deny가 더 안전함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-2. 파서 불일치 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 검증기가 해석한 명령과 실제 셸이 해석한 명령이 다르면, 검증은 존재해도 무력화될 수 있습니다. 이것은 웹 보안에서 입력 검증 로직과 실제 실행 로직이 다른 경우와 매우 유사합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-3. 신뢰 경계와 설정 파일 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repo 내부 설정이나 로컬 설정이 trust prompt 이전 동작에 영향을 줄 수 있다면, 사용자는 신뢰 여부를 결정하기도 전에 민감한 동작에 노출될 수 있습니다. 이 부분은 AI 에이전트 보안에서 계속 반복적으로 등장하는 핵심 리스크입니다.&lt;/p&gt;
&lt;div class=&quot;caludecodehack_warn&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;br /&gt;설정 파일, 권한 룰, 샌드박스, 승인 흐름이 서로 다른 기준으로 움직이면 반드시 틈이 생깁니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec6&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 개발자와 조직이 지금 점검해야 할 대응책&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개발사 입장에서 가장 중요한 것&lt;/h3&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;배포 파일 경계 관리 : &lt;/span&gt;deny 방식보다 allowlist 방식으로 패키지 포함 파일을 강하게 통제해야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;아티팩트 검사 자동화 : &lt;/span&gt;배포 직전 source map, 디버그 파일, 대용량 파일 포함 여부를 CI 단계에서 자동 차단해야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;크기 이상 탐지 : &lt;/span&gt;평소보다 패키지 용량이 급증하면 배포를 막는 장치가 필요합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;수동 배포 최소화 : &lt;/span&gt;사람 손을 타는 릴리즈 프로세스는 바쁜 상황에서 반드시 누락이 생깁니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;일반 개발팀이 당장 할 수 있는 것&lt;/h3&gt;
&lt;ul class=&quot;caludecodehack_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;의심 저장소 실행 금지 : &lt;/span&gt;유출 소스를 사칭하는 저장소, ZIP, 실행 파일은 절대 바로 실행하지 말아야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;격리 환경 우선 : &lt;/span&gt;신뢰되지 않은 repo에서는 devcontainer, VM, 샌드박스 환경을 우선 사용해야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;방어 심층화 : &lt;/span&gt;deny rule만 믿지 말고 샌드박스와 훅, 네트워크 제한을 함께 걸어야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caludecodehack_label&quot;&gt;보안 버전 유지 : &lt;/span&gt;관련 보안 권고가 나온 버전은 가능한 빨리 최신 버전으로 끌어올려야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;caludecodehack_ok&quot;&gt;&lt;b&gt;실무 한 줄 조언&lt;/b&gt;&lt;br /&gt;AI 에이전트 도구는 무엇을 할 수 있는가보다 무엇을 절대 못 하게 막을 것인가를 먼저 정해야 안전합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec7&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 마무리, 이번 사건이 남긴 진짜 교훈&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code 소스 유출 사건은 AI 시대의 보안 문제가 더 이상 모델 자체에만 머물지 않는다는 점을 강하게 보여줬습니다. 실제로 더 위험한 것은 배포 자동화, 패키징 위생, 권한 정책, 샌드박스, 설정 파일 신뢰 경계처럼 제품 외곽을 이루는 운영 구조일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 이번 사건에서 가장 크게 느껴지는 지점은 이것입니다. 좋은 AI 제품은 단지 똑똑한 모델로 만들어지는 것이 아니라, 실수할 수밖에 없는 배포 과정을 얼마나 견고하게 감싸고 있느냐로 완성됩니다.&lt;/p&gt;
&lt;div class=&quot;caludecodehack_quote&quot;&gt;AI 제품을 무너뜨리는 가장 현실적인 원인은, 종종 AI가 아니라 사람이 만든 배포 절차입니다.&lt;/div&gt;
&lt;div class=&quot;caludecodehack_tags&quot;&gt;&lt;span&gt;#ClaudeCode&lt;/span&gt; &lt;span&gt;#소스유출&lt;/span&gt; &lt;span&gt;#AI보안&lt;/span&gt; &lt;span&gt;#DevSecOps&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;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec8&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 자주 묻는 질문 Q&amp;amp;A&lt;/h2&gt;
&lt;div class=&quot;caludecodehack_faq&quot;&gt;&lt;details open=&quot;&quot;&gt;
&lt;summary&gt;Q. 이번 사건은 모델 자체 유출이라고 봐야 하나요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A. 공개된 흐름 기준으로는 모델 가중치 전체 유출보다는 Claude Code 운영 구조와 구현 디테일이 외부 분석 대상이 된 사건으로 보는 편이 더 정확합니다.&lt;/p&gt;
&lt;/details&gt;&lt;details&gt;
&lt;summary&gt;Q. 일반 개발자에게도 실제 위험이 있나요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A. 있습니다. 유출 소스를 사칭한 저장소, 악성 설치 파일, 취약한 설정을 가진 프로젝트를 통해 2차 피해가 이어질 수 있기 때문입니다.&lt;/p&gt;
&lt;/details&gt;&lt;details&gt;
&lt;summary&gt;Q. 가장 현실적인 대응은 무엇인가요?&lt;/summary&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A. 신뢰되지 않은 저장소는 격리 환경에서만 다루고, AI 에이전트 도구의 권한 정책과 샌드박스 규칙을 기본 차단형으로 운영하는 것이 가장 현실적입니다.&lt;/p&gt;
&lt;/details&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;caludecodehack_sec9&quot; class=&quot;caludecodehack_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9. 참고 자료&lt;/h2&gt;
&lt;ul class=&quot;caludecodehack_refs&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theverge.com/ai-artificial-intelligence/904776/anthropic-claude-source-code-leak&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The Verge - Claude Code leak 관련 보도&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anthropic.com/engineering/claude-code-auto-mode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Anthropic Engineering - Claude Code Auto Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.claude.com/docs/en/permissions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Claude Code Docs - Permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.claude.com/docs/en/sandboxing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Claude Code Docs - Sandboxing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/advisories/GHSA-jh7p-qr78-84p7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;GitHub Security Advisory - GHSA-jh7p-qr78-84p7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2026-21852&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NVD - CVE-2026-21852&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://adversa.ai/claude-code-security-bypass-deny-rules-disabled/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Adversa - deny rule bypass 분석&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>AnthropicAI보안</category>
      <category>claudecode</category>
      <category>DevSecOps</category>
      <category>SourceMAP</category>
      <category>개발자분석</category>
      <category>공급망보안</category>
      <category>샌드박스</category>
      <category>소스유출</category>
      <category>에이전트보안</category>
      <category>클로드코드소스유출</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/579</guid>
      <comments>https://odinbox.tistory.com/579#entry579comment</comments>
      <pubDate>Sat, 4 Apr 2026 17:07:31 +0900</pubDate>
    </item>
    <item>
      <title>99% 어셈블리어로 만든 전설, 롤러코스터 타이쿤의 최적화 비밀</title>
      <link>https://odinbox.tistory.com/578</link>
      <description>&lt;div&gt;
&lt;style&gt;
  .assemblylang_wrap {
    --assemblylang_bg: #ffffff;
    --assemblylang_text: #1f2937;
    --assemblylang_muted: #6b7280;
    --assemblylang_line: #e5e7eb;
    --assemblylang_soft: #f8fafc;
    --assemblylang_soft2: #f3f4f6;
    --assemblylang_point: #0f172a;
    --assemblylang_point2: #2563eb;
    --assemblylang_point3: #111827;
    --assemblylang_quote: #eff6ff;
    --assemblylang_warn: #fff7ed;
    --assemblylang_green: #ecfdf5;
    --assemblylang_green_line: #a7f3d0;
    --assemblylang_code_bg: #0b1220;
    --assemblylang_code_head: #111827;
    --assemblylang_code_text: #e5eefc;
    --assemblylang_radius: 18px;
    --assemblylang_shadow: 0 14px 32px rgba(15, 23, 42, 0.08);
    max-width: 860px;
    margin: 0 auto;
    color: var(--assemblylang_text);
    font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Pretendard&quot;, &quot;Apple SD Gothic Neo&quot;, &quot;Noto Sans KR&quot;, sans-serif;
    line-height: 1.85;
    word-break: keep-all;
    overflow-wrap: break-word;
  }

  .assemblylang_wrap * {
    box-sizing: border-box;
  }

  .assemblylang_wrap a {
    color: var(--assemblylang_point2);
    text-decoration: none;
  }

  .assemblylang_wrap img {
    max-width: 100%;
    height: auto;
    border-radius: 14px;
  }

  .assemblylang_kicker {
    display: inline-block;
    margin: 8px 0 14px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--assemblylang_soft2);
    color: var(--assemblylang_point3);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
  }

  .assemblylang_title {
    margin: 0 0 14px;
    font-size: 36px;
    line-height: 1.35;
    color: var(--assemblylang_point);
    font-weight: 800;
    letter-spacing: -0.03em;
  }

  .assemblylang_subtitle {
    margin: 0 0 18px;
    font-size: 18px;
    line-height: 1.72;
    color: var(--assemblylang_muted);
  }

  .assemblylang_meta {
    margin: 0 0 26px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--assemblylang_line);
    color: var(--assemblylang_muted);
    font-size: 14px;
  }

  .assemblylang_card,
  .assemblylang_leadbox,
  .assemblylang_toc,
  .assemblylang_infobox,
  .assemblylang_quotebox,
  .assemblylang_sourcebox,
  .assemblylang_tagbox,
  .assemblylang_warnbox,
  .assemblylang_greenbox {
    margin: 24px 0;
    padding: 24px;
    border: 1px solid var(--assemblylang_line);
    border-radius: var(--assemblylang_radius);
    background: var(--assemblylang_bg);
    box-shadow: var(--assemblylang_shadow);
  }

  .assemblylang_leadbox {
    background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%);
  }

  .assemblylang_infobox {
    background: var(--assemblylang_soft);
  }

  .assemblylang_quotebox {
    background: var(--assemblylang_quote);
    border-color: #bfdbfe;
  }

  .assemblylang_warnbox {
    background: var(--assemblylang_warn);
    border-color: #fed7aa;
  }

  .assemblylang_greenbox {
    background: var(--assemblylang_green);
    border-color: var(--assemblylang_green_line);
  }

  .assemblylang_box_title {
    margin: 0 0 14px;
    font-size: 18px;
    font-weight: 800;
    color: var(--assemblylang_point);
  }

  .assemblylang_summary_list,
  .assemblylang_plain_list {
    margin: 0;
    padding-left: 20px;
  }

  .assemblylang_summary_list li,
  .assemblylang_plain_list li {
    margin: 10px 0;
  }

  .assemblylang_toc {
    background: var(--assemblylang_soft);
  }

  .assemblylang_toc_title {
    margin: 0 0 12px;
    font-size: 17px;
    font-weight: 800;
    color: var(--assemblylang_point);
  }

  .assemblylang_toc ol {
    margin: 0;
    padding-left: 20px;
  }

  .assemblylang_toc li {
    margin: 8px 0;
  }

  .assemblylang_section {
    margin: 48px 0 0;
  }

  .assemblylang_section h2 {
    margin: 0 0 16px;
    font-size: 30px;
    line-height: 1.42;
    color: var(--assemblylang_point);
    font-weight: 800;
    letter-spacing: -0.02em;
  }

  .assemblylang_section h3 {
    margin: 28px 0 12px;
    font-size: 22px;
    line-height: 1.5;
    color: var(--assemblylang_point3);
    font-weight: 800;
    letter-spacing: -0.02em;
  }

  .assemblylang_section p {
    margin: 0 0 16px;
    font-size: 17px;
  }

  .assemblylang_emphasis {
    color: var(--assemblylang_point);
    font-weight: 800;
  }

  .assemblylang_compare {
    width: 100%;
    border-collapse: collapse;
    margin: 18px 0 8px;
    overflow: hidden;
    border-radius: 14px;
  }

  .assemblylang_compare th,
  .assemblylang_compare td {
    border: 1px solid var(--assemblylang_line);
    padding: 14px 12px;
    vertical-align: top;
    text-align: left;
    font-size: 15px;
  }

  .assemblylang_compare thead th {
    background: #f8fafc;
    color: var(--assemblylang_point);
    font-weight: 800;
  }

  .assemblylang_code_wrap {
    margin: 18px 0;
    border-radius: 16px;
    overflow: hidden;
    background: var(--assemblylang_code_bg) !important;
    border: 1px solid #1e293b;
    box-shadow: 0 12px 24px rgba(2, 6, 23, 0.18);
  }

  .assemblylang_code_head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    background: var(--assemblylang_code_head) !important;
    color: #e5e7eb !important;
    font-size: 13px;
    font-weight: 700;
    border-bottom: 1px solid #1f2937;
  }

  .assemblylang_code_wrap pre {
    margin: 0 !important;
    padding: 18px !important;
    overflow-x: auto;
    overflow-y: hidden;
    background: var(--assemblylang_code_bg) !important;
    color: var(--assemblylang_code_text) !important;
    font-size: 14px;
    line-height: 1.72;
    font-family: Consolas, &quot;Fira Code&quot;, &quot;D2Coding&quot;, monospace !important;
    white-space: pre !important;
    word-break: normal !important;
    overflow-wrap: normal !important;
    tab-size: 4;
    -webkit-text-fill-color: var(--assemblylang_code_text) !important;
  }

  .assemblylang_code_wrap code {
    display: block;
    background: var(--assemblylang_code_bg) !important;
    color: var(--assemblylang_code_text) !important;
    font-size: 14px;
    line-height: 1.72;
    font-family: Consolas, &quot;Fira Code&quot;, &quot;D2Coding&quot;, monospace !important;
    white-space: pre !important;
    word-break: normal !important;
    overflow-wrap: normal !important;
    -webkit-text-fill-color: var(--assemblylang_code_text) !important;
  }

  .assemblylang_code_wrap pre *,
  .assemblylang_code_wrap code * {
    color: inherit !important;
    -webkit-text-fill-color: inherit !important;
  }

  .assemblylang_code_wrap .hljs,
  .assemblylang_code_wrap .hljs-subst {
    background: var(--assemblylang_code_bg) !important;
    color: var(--assemblylang_code_text) !important;
  }

  .assemblylang_code_wrap .hljs-comment,
  .assemblylang_code_wrap .hljs-quote {
    color: #94a3b8 !important;
  }

  .assemblylang_code_wrap .hljs-keyword,
  .assemblylang_code_wrap .hljs-selector-tag,
  .assemblylang_code_wrap .hljs-built_in,
  .assemblylang_code_wrap .hljs-name,
  .assemblylang_code_wrap .hljs-tag {
    color: #93c5fd !important;
  }

  .assemblylang_code_wrap .hljs-string,
  .assemblylang_code_wrap .hljs-attr,
  .assemblylang_code_wrap .hljs-doctag,
  .assemblylang_code_wrap .hljs-template-tag,
  .assemblylang_code_wrap .hljs-template-variable {
    color: #86efac !important;
  }

  .assemblylang_code_wrap .hljs-number,
  .assemblylang_code_wrap .hljs-literal,
  .assemblylang_code_wrap .hljs-symbol,
  .assemblylang_code_wrap .hljs-bullet {
    color: #fbbf24 !important;
  }

  .assemblylang_code_wrap .hljs-title,
  .assemblylang_code_wrap .hljs-section,
  .assemblylang_code_wrap .hljs-function {
    color: #c4b5fd !important;
  }

  .assemblylang_code_wrap .hljs-variable,
  .assemblylang_code_wrap .hljs-regexp,
  .assemblylang_code_wrap .hljs-link {
    color: #fca5a5 !important;
  }

  .assemblylang_keyword {
    display: inline-block;
    margin: 6px 8px 0 0;
    padding: 7px 12px;
    border-radius: 999px;
    background: var(--assemblylang_soft2);
    color: var(--assemblylang_point3);
    font-size: 13px;
    font-weight: 700;
  }

  .assemblylang_conclusion {
    margin-top: 44px;
    padding: 28px;
    border-radius: 22px;
    background: linear-gradient(135deg, #111827 0%, #1e293b 100%);
    color: #ffffff;
  }

  .assemblylang_conclusion h2 {
    margin: 0 0 14px;
    font-size: 28px;
    line-height: 1.4;
    color: #ffffff;
  }

  .assemblylang_conclusion p {
    margin: 0 0 12px;
    font-size: 17px;
    color: rgba(255,255,255,0.92);
  }

  .assemblylang_source_list {
    margin: 12px 0 0;
    padding-left: 20px;
  }

  .assemblylang_source_list li {
    margin: 8px 0;
    font-size: 15px;
    color: var(--assemblylang_muted);
  }

  @media (max-width: 768px) {
    .assemblylang_title {
      font-size: 28px;
    }

    .assemblylang_subtitle {
      font-size: 16px;
    }

    .assemblylang_section h2 {
      font-size: 25px;
    }

    .assemblylang_section h3 {
      font-size: 20px;
    }

    .assemblylang_card,
    .assemblylang_leadbox,
    .assemblylang_toc,
    .assemblylang_infobox,
    .assemblylang_quotebox,
    .assemblylang_sourcebox,
    .assemblylang_tagbox,
    .assemblylang_warnbox,
    .assemblylang_greenbox,
    .assemblylang_conclusion {
      padding: 18px;
      border-radius: 16px;
    }

    .assemblylang_compare th,
    .assemblylang_compare td {
      font-size: 14px;
      padding: 12px 10px;
    }

    .assemblylang_code_head {
      flex-direction: column;
      align-items: flex-start;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;!--
assemblylang_seo_title: 전설이 된 코드, 롤러코스터 타이쿤과 어셈블리어가 만든 최적화의 기적
assemblylang_seo_description: 롤러코스터 타이쿤은 왜 지금도 최적화의 전설로 불릴까. 크리스 소이어의 1인 개발, 99% x86 어셈블리, 데이터 레이아웃, 비트시프트, OpenRCT2, 예시 어셈블리 코드까지 한 번에 정리합니다.
assemblylang_seo_keywords: 롤러코스터타이쿤, 어셈블리어, 크리스소이어, x86 assembly, game optimization, OpenRCT2, 데이터 레이아웃, 비트시프트, 1인 개발, 소프트웨어 공학
--&gt;
&lt;div class=&quot;assemblylang_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nWgYI/dJMcaaxYNqY/87gsL0brY4hh873vWq1N61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nWgYI/dJMcaaxYNqY/87gsL0brY4hh873vWq1N61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nWgYI/dJMcaaxYNqY/87gsL0brY4hh873vWq1N61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnWgYI%2FdJMcaaxYNqY%2F87gsL0brY4hh873vWq1N61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;assemblylang_kicker&quot;&gt;게임개발 &amp;middot; 어셈블리어 &amp;middot; 최적화 &amp;middot; 소프트웨어공학&lt;/div&gt;
&lt;h1 class=&quot;assemblylang_title&quot;&gt;전설이 된 코드&lt;/h1&gt;
&lt;h1 class=&quot;assemblylang_title&quot;&gt;롤러코스터 타이쿤과 어셈블리어가 만든 최적화의 기적&lt;/h1&gt;
&lt;p class=&quot;assemblylang_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;1999년의 PC에서 수천 명의 손님과 수십 개의 놀이기구를 동시에 굴린 게임. 그리고 그 중심에는 지금 봐도 믿기 어려운 선택, 거의 전부를 저수준 코드로 밀어붙인 개발 방식이 있었습니다. &lt;b&gt;롤러코스터 타이쿤&lt;/b&gt;은 단순한 명작 게임이 아니라, 지금도 개발자들이 최적화와 시스템 설계를 이야기할 때 빠지지 않는 사례입니다.&lt;/p&gt;
&lt;p class=&quot;assemblylang_meta&quot; data-ke-size=&quot;size16&quot;&gt;롤러코스터 타이쿤 &amp;middot; 크리스 소이어 &amp;middot; 어셈블리어 &amp;middot; x86 &amp;middot; 게임 최적화 &amp;middot; OpenRCT2 &amp;middot; 데이터 레이아웃 &amp;middot; 비트시프트 &amp;middot; 1인 개발&lt;/p&gt;
&lt;div class=&quot;assemblylang_leadbox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;핵심만 먼저 보면&lt;/p&gt;
&lt;ul class=&quot;assemblylang_summary_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;롤러코스터 타이쿤은 단순한 추억의 게임이 아니라 &lt;b&gt;최적화 설계의 대표 사례&lt;/b&gt;로 자주 언급됩니다.&lt;/li&gt;
&lt;li&gt;크리스 소이어는 당시 하드웨어 한계 속에서 원하는 시뮬레이션을 구현하기 위해 &lt;b&gt;매우 낮은 수준의 제어&lt;/b&gt;를 선택했습니다.&lt;/li&gt;
&lt;li&gt;이 게임의 강점은 &amp;ldquo;어셈블리어를 썼다&amp;rdquo;에서 끝나지 않습니다. &lt;b&gt;데이터 구조, 수식, 길찾기, 군중 처리까지 전부 성능 중심으로 설계&lt;/b&gt;됐다는 점이 핵심입니다.&lt;/li&gt;
&lt;li&gt;반대로 이런 방식은 훗날 이식성과 유지보수성에서 큰 대가를 남겼고, 그래서 OpenRCT2 같은 재구현 프로젝트가 더욱 의미를 가지게 됐습니다.&lt;/li&gt;
&lt;li&gt;결국 이 사례가 남기는 질문은 하나입니다. &lt;b&gt;우리는 추상화 아래에서 실제 비용 구조를 얼마나 이해하고 있는가&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;assemblylang_toc&quot;&gt;
&lt;p class=&quot;assemblylang_toc_title&quot; data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section1&quot;&gt;왜 롤러코스터 타이쿤은 아직도 전설인가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section2&quot;&gt;어셈블리어란 무엇인가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section3&quot;&gt;1990년대 하드웨어가 만든 선택&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section4&quot;&gt;크리스 소이어의 1인 개발 방식&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section5&quot;&gt;최적화의 황금 표준으로 불리는 이유&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section6&quot;&gt;예시 어셈블리 소스가 왜 도움이 되는가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section7&quot;&gt;성능을 위해 게임 디자인까지 바꾼 사례&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section8&quot;&gt;어셈블리어의 대가와 OpenRCT2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assemblylang_section9&quot;&gt;현대 개발자가 얻을 수 있는 교훈&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section1&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 롤러코스터 타이쿤은 아직도 전설인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤러코스터 타이쿤은 단순히 재미있는 테마파크 경영 게임이 아닙니다. 이 게임은 거대한 공원을 보여주면서도 손님들의 이동, 기구의 상태, 수익과 동선, 만족도와 혼잡도 같은 여러 시스템을 동시에 굴립니다. 그런데 놀라운 점은 이 복잡한 구조가 1999년의 PC 환경에서도 상당히 부드럽게 돌아갔다는 것입니다.&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;지금처럼 강력한 CPU와 대용량 메모리, 정교한 컴파일러가 보편적이지 않던 시절에 이 정도 규모의 시뮬레이션을 구현했다는 것만으로도 이미 대단하지만, 이 작품이 더 특별한 이유는 그 구현 방식에 있습니다. 롤러코스터 타이쿤은 &amp;ldquo;고수준 언어와 대규모 팀&amp;rdquo;이라는 현대적 방식과는 다른 길을 택했고, 그 결과 지금도 개발자 사이에서 &lt;span class=&quot;assemblylang_emphasis&quot;&gt;최적화의 전설&lt;/span&gt;로 불립니다.&lt;/p&gt;
&lt;div class=&quot;assemblylang_quotebox&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤러코스터 타이쿤의 진짜 무게감은 단순히 &amp;ldquo;혼자 만들었다&amp;rdquo;가 아닙니다. &lt;b&gt;제약이 심한 시대에, 성능과 설계를 같은 손으로 끝까지 밀어붙였다&lt;/b&gt;는 데 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section2&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어셈블리어란 무엇인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 본질적으로 0과 1로 이뤄진 기계어만 이해합니다. 어셈블리어는 그 기계어를 사람이 그나마 읽을 수 있도록 바꿔놓은 가장 낮은 단계의 프로그래밍 언어입니다. 우리가 흔히 사용하는 C, C++, Java, C#, Python 같은 언어가 &amp;ldquo;무엇을 할지&amp;rdquo;를 상대적으로 높은 수준에서 표현한다면, 어셈블리어는 &lt;b&gt;어느 레지스터에 무엇을 넣고, 어떤 메모리를 읽고, 어떤 순서로 연산할지&lt;/b&gt;까지 매우 세밀하게 지시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 비유하면 고수준 언어는 이미 만들어진 블록을 조립하는 방식에 가깝고, 어셈블리어는 그 블록의 모양과 내부 구조까지 직접 깎는 일에 가깝습니다. 그래서 성능은 강력하지만, 생산성과 유지보수성은 매우 낮습니다.&lt;/p&gt;
&lt;div class=&quot;assemblylang_infobox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;어셈블리어를 이해할 때 핵심&lt;/p&gt;
&lt;ul class=&quot;assemblylang_plain_list&quot; 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;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section3&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1990년대 하드웨어가 만든 선택&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 기준으로는 &amp;ldquo;왜 굳이 그렇게까지?&amp;rdquo;라는 질문이 자연스럽습니다. 하지만 1990년대 후반 PC 환경은 지금과 완전히 달랐습니다. CPU 성능은 훨씬 낮았고, 메모리도 넉넉하지 않았으며, 오늘날처럼 컴파일러가 광범위한 최적화를 대신해 주는 시대도 아니었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 환경에서 수천 명의 손님, 복잡한 기구 상태, 대규모 공원 화면을 동시에 유지하려면 단순히 코드를 잘 짜는 수준을 넘어 &lt;b&gt;무엇을 어떤 형태로 저장하고 계산할지&lt;/b&gt;까지 매우 집요하게 설계해야 했습니다. 당시 크리스 소이어에게 저수준 제어는 취향의 문제가 아니라, 원하는 수준의 결과를 내기 위한 현실적인 선택에 가까웠습니다.&lt;/p&gt;
&lt;table class=&quot;assemblylang_compare&quot; 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;저수준 어셈블리 중심 개발&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&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;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;div id=&quot;assemblylang_section4&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;크리스 소이어의 1인 개발 방식&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dirYxB/dJMcahw6FHC/pKGFdCwiQwN48lFFcVZB71/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dirYxB/dJMcahw6FHC/pKGFdCwiQwN48lFFcVZB71/img.webp&quot; data-alt=&quot;크리스소이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dirYxB/dJMcahw6FHC/pKGFdCwiQwN48lFFcVZB71/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdirYxB%2FdJMcahw6FHC%2FpKGFdCwiQwN48lFFcVZB71%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;416&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크리스소이&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;롤러코스터 타이쿤의 가치가 더 크게 느껴지는 이유는, 이 게임이 단지 특정 언어를 썼기 때문만은 아니라는 점입니다. 크리스 소이어는 게임 디자이너이면서 동시에 핵심 프로그래머 역할을 함께 수행했고, 그래서 &amp;ldquo;게임이 어떻게 느껴져야 하는가&amp;rdquo;와 &amp;ldquo;그걸 어떤 비용으로 구현할 것인가&amp;rdquo;를 같은 머리에서 통합해 판단할 수 있었습니다.&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;widthOrigin&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccQhq5/dJMcaaSicu1/zBzYMkMpec7vO6v5KTS6c1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccQhq5/dJMcaaSicu1/zBzYMkMpec7vO6v5KTS6c1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccQhq5/dJMcaaSicu1/zBzYMkMpec7vO6v5KTS6c1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccQhq5%2FdJMcaaSicu1%2FzBzYMkMpec7vO6v5KTS6c1%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;335&quot; height=&quot;188&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;현대의 대규모 개발이 역할 분업과 문서 중심으로 흘러간다면, 그의 방식은 작동하는 구조를 먼저 만들고 그 위에 쌓아 올리는 바텀업 접근에 가까웠습니다. 이 방식은 위험하지만, 성능 최적화와 시스템 일관성을 동시에 잡는 데는 매우 강력합니다.&lt;/p&gt;
&lt;div class=&quot;assemblylang_greenbox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;이 방식이 강력했던 이유&lt;/p&gt;
&lt;ul class=&quot;assemblylang_plain_list&quot; 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;ldquo;재미&amp;rdquo;와 &amp;ldquo;속도&amp;rdquo;를 같은 관점에서 설계할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section5&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;최적화의 황금 표준으로 불리는 이유&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 값의 크기에 따라 자료형을 더 잘게 나눴다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 개발에서는 그냥 넉넉한 자료형을 쓰는 일이 흔하지만, 롤러코스터 타이쿤은 값의 범위에 맞춰 필요한 크기만 사용하는 식의 세밀한 선택이 보입니다. 전체 공원 가치처럼 큰 값은 더 크게, 매점 가격처럼 범위가 작은 값은 더 작게 다루는 식입니다. 이런 선택은 지금 보면 소소해 보일 수 있지만, 수많은 값이 동시에 움직이는 시뮬레이션에서는 누적 효과가 분명합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 곱셈과 나눗셈을 비트시프트 친화적으로 설계했다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2, 4, 8 같은 값은 비트시프트로 빠르게 계산할 수 있습니다. 더 흥미로운 점은 단순히 코드 레벨에서만 그런 최적화를 한 것이 아니라, 아예 게임 안의 수식이 이런 계산 방식과 잘 맞도록 설계된 흔적이 보인다는 것입니다. 이건 &amp;ldquo;코드를 빨리 짰다&amp;rdquo;가 아니라 &lt;b&gt;설계 자체가 CPU 친화적이었다&lt;/b&gt;는 뜻에 가깝습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 데이터 레이아웃 자체가 성능의 핵심이었다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 무서운 부분은 명령어 하나하나보다 데이터 구조입니다. 무엇을 어떻게 저장하고, 어떤 순서로 읽고, 얼마나 자주 접근할지 자체가 성능을 좌우합니다. 롤러코스터 타이쿤이 전설이 된 이유는 단지 저수준 언어를 썼기 때문이 아니라, &lt;b&gt;데이터를 CPU가 좋아하는 방식으로 최대한 빽빽하게 설계했다&lt;/b&gt;는 데 있습니다.&lt;/p&gt;
&lt;div class=&quot;assemblylang_quotebox&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 최적화는 &amp;ldquo;코드 몇 줄을 빨리 돌게 만드는 것&amp;rdquo;보다, &lt;b&gt;애초에 어떤 데이터와 규칙을 어떤 구조로 배치할지를 잘 정하는 것&lt;/b&gt;에서 시작됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section6&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예시 어셈블리 소스가 왜 도움이 되는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 글에서 예시 어셈블리 소스를 넣는 것은 분명 도움이 됩니다. 다만 중요한 점은, 이 예시가 실제 Chris Sawyer의 원본 소스가 아니라 &lt;b&gt;본문에서 설명한 최적화 감각을 이해하기 위한 개념 예시&lt;/b&gt;라는 점을 분명히 해야 한다는 것입니다.&lt;/p&gt;
&lt;div class=&quot;assemblylang_warnbox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;주의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드는 &lt;b&gt;원본 RollerCoaster Tycoon 소스가 아닙니다.&lt;/b&gt;&lt;br /&gt;비트시프트, 플래그 검사, 짧은 분기, 단순 상태 갱신이 어떤 느낌인지 보여주기 위한 &lt;b&gt;이해용 x86 스타일 예시&lt;/b&gt;입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;assemblylang_code_wrap&quot;&gt;
&lt;div class=&quot;assemblylang_code_head&quot;&gt;&lt;span&gt;assemblylang_example_x86.asm&lt;/span&gt; &lt;span&gt;개념 이해용 예시&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;x86asm&quot;&gt;&lt;code&gt;; -----------------------------------------
; 이해용 예시: 손님의 상태 일부를 매우 저수준으로 갱신하는 느낌
; 실제 RCT 원본 소스 아님
; -----------------------------------------

section .data
assemblylang_guest_hunger      db 48      ; 0~255 범위
assemblylang_guest_flags       db 00000101b
assemblylang_guest_happiness   db 120

section .text
global assemblylang_update_guest_state

assemblylang_update_guest_state:
    ; eax, ebx 사용 예시
    xor eax, eax
    xor ebx, ebx

    ; hunger 값을 읽음
    mov al, [assemblylang_guest_hunger]

    ; /8 대신 &amp;gt;&amp;gt; 3 사용
    shr al, 3

    ; 배고픔 단계가 6 이상이면 행복도 감소
    cmp al, 6
    jl assemblylang_check_flags

    mov bl, [assemblylang_guest_happiness]
    sub bl, 2
    mov [assemblylang_guest_happiness], bl

assemblylang_check_flags:
    ; bit 2 = 지도 보유
    mov al, [assemblylang_guest_flags]
    test al, 00000100b
    jz assemblylang_done

    nop

assemblylang_done:
    ret&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시에서 중요한 포인트는 문법 자체보다도 감각입니다. &lt;b&gt;작은 자료형, 비트 단위 플래그, 짧은 분기, 곱셈/나눗셈 대신 시프트 활용&lt;/b&gt; 같은 요소가 저수준 최적화의 분위기를 보여줍니다. 본문에 이런 예시가 들어가면 독자는 &amp;ldquo;어셈블리어로 작성됐다&amp;rdquo;는 문장을 더 구체적으로 이해하게 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section7&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;성능을 위해 게임 디자인까지 바꾼 사례&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYpS6t/dJMcagLJNOo/XcH8z1s9o5tubdDghM1plK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYpS6t/dJMcagLJNOo/XcH8z1s9o5tubdDghM1plK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYpS6t/dJMcagLJNOo/XcH8z1s9o5tubdDghM1plK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYpS6t%2FdJMcagLJNOo%2FXcH8z1s9o5tubdDghM1plK%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;640&quot; height=&quot;365&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&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;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;물론 모든 상황을 그렇게 처리한 것은 아닙니다. 정비공이 고장 난 기구로 이동하거나, 손님이 출구를 찾아야 하는 경우처럼 중요한 순간에는 더 전통적인 길 찾기가 필요합니다. 다만 여기서도 탐색 깊이에 제한을 둬서, 하나의 길 찾기 요청이 프레임 전체를 무너뜨리지 않게 했다는 점이 중요합니다.&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;div class=&quot;assemblylang_infobox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;이 지점이 특히 중요한 이유&lt;/p&gt;
&lt;ul class=&quot;assemblylang_plain_list&quot; 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;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section8&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어셈블리어의 대가와 OpenRCT2&lt;/h2&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;OpenRCT2&lt;/b&gt;입니다. 이 프로젝트는 단순한 모드가 아니라, 원작 계열 게임의 동작을 분석하고 현대 환경에서 더 편하게 즐길 수 있도록 이어주는 재구현 프로젝트라는 점에서 의미가 큽니다.&lt;/p&gt;
&lt;div class=&quot;assemblylang_quotebox&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능을 위해 가장 낮은 수준까지 내려간 선택은 훗날 유지보수성을 희생시켰지만, 역으로 그 덕분에 OpenRCT2 같은 집요한 재구현 프로젝트가 더 큰 기술적 가치를 갖게 되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;assemblylang_section9&quot; class=&quot;assemblylang_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;현대 개발자가 얻을 수 있는 교훈&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사례를 보고 &amp;ldquo;역시 어셈블리어가 정답이다&amp;rdquo;라고 결론 내리면 오해입니다. 오늘날 대부분의 소프트웨어는 고수준 언어와 성숙한 툴체인 위에서 개발하는 편이 훨씬 합리적입니다. 생산성, 유지보수성, 협업성, 이식성을 무시할 수 없기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 롤러코스터 타이쿤이 지금도 강하게 남는 이유는 따로 있습니다. &lt;b&gt;성능 문제는 마지막에 튜닝 몇 번 해서 해결되는 것이 아니라, 처음에 데이터와 규칙을 어떻게 설계하느냐에서 이미 절반 이상 결정된다&lt;/b&gt;는 점을 분명하게 보여주기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 한 가지 더 있습니다. 좋은 개발자는 단순히 프레임워크를 잘 쓰는 사람이 아니라, 그 아래에서 실제로 어떤 비용이 발생하는지 상상할 수 있는 사람에 가깝습니다. 결국 롤러코스터 타이쿤이 남긴 가장 큰 유산은 &amp;ldquo;낮은 수준을 무조건 쓰라&amp;rdquo;가 아니라, &lt;b&gt;하드웨어와 런타임 비용을 이해하는 감각을 잃지 말라&lt;/b&gt;는 말에 더 가깝습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;assemblylang_conclusion&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리, 전설은 언어보다 설계에서 나온다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤러코스터 타이쿤은 오래된 명작 게임이면서 동시에, 제약이 심한 시대에 얼마나 집요한 설계와 최적화가 가능한지를 보여주는 작품입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이 게임은 지금도 개발자에게 질문을 던집니다. &lt;b&gt;당신은 코드만 보고 있는가, 아니면 그 아래의 비용 구조까지 보고 있는가&lt;/b&gt;. 이 질문이야말로 롤러코스터 타이쿤이 아직도 전설로 남아 있는 진짜 이유일 것입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;assemblylang_sourcebox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;참고 및 출처&lt;/p&gt;
&lt;ul class=&quot;assemblylang_source_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Chris Sawyer 공식 FAQ 기준으로 RollerCoaster Tycoon은 99% x86 assembler/machine code와 소량의 C로 작성되었다고 소개됩니다.&lt;/li&gt;
&lt;li&gt;Lars Tofus, &lt;i&gt;The gold standard of optimization: A look under the hood of RollerCoaster Tycoon&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;OpenRCT2 프로젝트 및 재구현/역분석 관련 공개 자료&lt;/li&gt;
&lt;li&gt;업로드한 원고 내용을 바탕으로 전체 흐름과 표현을 재구성했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;assemblylang_tagbox&quot;&gt;
&lt;p class=&quot;assemblylang_box_title&quot; data-ke-size=&quot;size16&quot;&gt;태그&lt;/p&gt;
&lt;span class=&quot;assemblylang_keyword&quot;&gt;#롤러코스터타이쿤&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#어셈블리어&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#크리스소이어&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#x86&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#게임개발&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#게임최적화&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#데이터레이아웃&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#비트시프트&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#OpenRCT2&lt;/span&gt; &lt;span class=&quot;assemblylang_keyword&quot;&gt;#소프트웨어공학&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>OpenRCT2</category>
      <category>x86어셈블리</category>
      <category>게임개발</category>
      <category>게임최적화</category>
      <category>데이터레이아웃</category>
      <category>롤러코스터타이쿤</category>
      <category>소프트웨어공학</category>
      <category>어셈블리어</category>
      <category>저수준언어</category>
      <category>크리스소이어</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/578</guid>
      <comments>https://odinbox.tistory.com/578#entry578comment</comments>
      <pubDate>Sun, 29 Mar 2026 13:07:10 +0900</pubDate>
    </item>
    <item>
      <title>울산 공공주택 유홈</title>
      <link>https://odinbox.tistory.com/577</link>
      <description>&lt;div&gt;
&lt;style&gt;
  :root {
    --ulsanhome_color_bg: #f4f7fb;
    --ulsanhome_color_surface: #ffffff;
    --ulsanhome_color_text: #1f2937;
    --ulsanhome_color_muted: #5b6472;
    --ulsanhome_color_line: #dbe4ee;
    --ulsanhome_color_primary: #0f4c81;
    --ulsanhome_color_primary_soft: #eaf3fb;
    --ulsanhome_color_accent: #0f766e;
    --ulsanhome_color_accent_soft: #ecfdf5;
    --ulsanhome_color_warn: #9a3412;
    --ulsanhome_color_warn_soft: #fff7ed;
    --ulsanhome_color_navy: #16324f;
    --ulsanhome_shadow_sm: 0 8px 22px rgba(15, 76, 129, 0.07);
    --ulsanhome_shadow_md: 0 18px 42px rgba(15, 76, 129, 0.12);
    --ulsanhome_radius_sm: 12px;
    --ulsanhome_radius_md: 18px;
    --ulsanhome_radius_lg: 26px;
    --ulsanhome_width: 980px;
    --ulsanhome_font: &quot;Pretendard&quot;, &quot;Noto Sans KR&quot;, &quot;Apple SD Gothic Neo&quot;, sans-serif;
  }

  .ulsanhome_wrap,
  .ulsanhome_wrap * {
    box-sizing: border-box;
  }

  .ulsanhome_wrap {
    max-width: var(--ulsanhome_width);
    margin: 0 auto;
    padding: 18px 0 56px;
    font-family: var(--ulsanhome_font);
    color: var(--ulsanhome_color_text);
    line-height: 1.9;
    word-break: keep-all;
  }

  .ulsanhome_hero {
    padding: 36px 28px;
    border-radius: var(--ulsanhome_radius_lg);
    background: linear-gradient(135deg, #0f4c81 0%, #1c6aa3 55%, #1f7a8c 100%);
    color: #ffffff;
    box-shadow: var(--ulsanhome_shadow_md);
    margin-bottom: 22px;
  }

  .ulsanhome_eyebrow {
    display: inline-block;
    padding: 6px 11px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
    margin-bottom: 14px;
  }

  .ulsanhome_title {
    margin: 0 0 10px;
    font-size: 34px;
    line-height: 1.34;
    font-weight: 800;
  }

  .ulsanhome_desc {
    margin: 0;
    font-size: 16px;
    color: rgba(255, 255, 255, 0.94);
  }

  .ulsanhome_visual {
    margin: 18px 0 28px;
    padding: 14px;
    background: #ffffff;
    border: 1px solid var(--ulsanhome_color_line);
    border-radius: var(--ulsanhome_radius_lg);
    box-shadow: var(--ulsanhome_shadow_sm);
  }

  .ulsanhome_visual p {
    margin: 0;
  }

  .ulsanhome_section {
    margin-top: 26px;
    background: var(--ulsanhome_color_surface);
    border: 1px solid var(--ulsanhome_color_line);
    border-radius: var(--ulsanhome_radius_md);
    box-shadow: var(--ulsanhome_shadow_sm);
    padding: 28px 22px;
  }

  .ulsanhome_section h2 {
    margin: 0 0 14px;
    font-size: 27px;
    line-height: 1.42;
    color: var(--ulsanhome_color_primary);
  }

  .ulsanhome_section h3 {
    margin: 26px 0 12px;
    font-size: 21px;
    line-height: 1.5;
    color: var(--ulsanhome_color_navy);
  }

  .ulsanhome_section p {
    margin: 0 0 14px;
    font-size: 16px;
  }

  .ulsanhome_info {
    margin: 18px 0;
    padding: 16px 18px;
    border-radius: var(--ulsanhome_radius_md);
    border: 1px solid transparent;
  }

  .ulsanhome_info--primary {
    background: var(--ulsanhome_color_primary_soft);
    border-color: #d3e5f5;
  }

  .ulsanhome_info--accent {
    background: var(--ulsanhome_color_accent_soft);
    border-color: #cdeee7;
  }

  .ulsanhome_info--warn {
    background: var(--ulsanhome_color_warn_soft);
    border-color: #ffd9c2;
  }

  .ulsanhome_toc {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    margin-top: 18px;
  }

  .ulsanhome_toc a {
    display: block;
    padding: 12px 14px;
    border-radius: 14px;
    text-decoration: none;
    color: var(--ulsanhome_color_primary);
    background: #f7fbff;
    border: 1px solid #d8e7f5;
    font-weight: 700;
    transition: all 0.2s ease;
  }

  .ulsanhome_toc a:hover {
    transform: translateY(-1px);
    background: #eef6fd;
  }

  .ulsanhome_grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    margin-top: 18px;
  }

  .ulsanhome_card {
    background: var(--ulsanhome_color_bg);
    border: 1px solid var(--ulsanhome_color_line);
    border-radius: var(--ulsanhome_radius_md);
    padding: 18px 16px;
  }

  .ulsanhome_card strong {
    display: block;
    margin-bottom: 8px;
    color: var(--ulsanhome_color_primary);
    font-size: 15px;
  }

  .ulsanhome_card p {
    margin: 0;
    font-size: 15px;
    color: var(--ulsanhome_color_muted);
  }

  .ulsanhome_list {
    margin: 10px 0 0;
    padding-left: 20px;
  }

  .ulsanhome_list li {
    margin-bottom: 8px;
  }

  .ulsanhome_table_wrap {
    overflow-x: auto;
    margin-top: 18px;
    border: 1px solid var(--ulsanhome_color_line);
    border-radius: var(--ulsanhome_radius_md);
  }

  .ulsanhome_table {
    width: 100%;
    min-width: 760px;
    border-collapse: collapse;
    background: #ffffff;
  }

  .ulsanhome_table th,
  .ulsanhome_table td {
    padding: 14px 12px;
    border-bottom: 1px solid var(--ulsanhome_color_line);
    text-align: left;
    vertical-align: top;
    font-size: 15px;
  }

  .ulsanhome_table th {
    background: #f1f6fb;
    color: var(--ulsanhome_color_primary);
    font-weight: 700;
  }

  .ulsanhome_table tr:last-child td {
    border-bottom: 0;
  }

  .ulsanhome_quote {
    margin-top: 18px;
    padding: 18px 20px;
    border-left: 5px solid var(--ulsanhome_color_primary);
    background: #f8fbfe;
    border-radius: 0 16px 16px 0;
    color: #24415c;
    font-size: 16px;
  }

  .ulsanhome_linkbox {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin-top: 18px;
  }

  .ulsanhome_linkcard {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: 18px 16px;
    border-radius: var(--ulsanhome_radius_md);
    border: 1px solid var(--ulsanhome_color_line);
    background: #fbfdff;
    transition: all 0.2s ease;
  }

  .ulsanhome_linkcard:hover {
    transform: translateY(-2px);
    box-shadow: var(--ulsanhome_shadow_sm);
  }

  .ulsanhome_linkcard strong {
    display: block;
    margin-bottom: 6px;
    color: var(--ulsanhome_color_primary);
  }

  .ulsanhome_faq_item {
    padding: 16px 0;
    border-bottom: 1px dashed var(--ulsanhome_color_line);
  }

  .ulsanhome_faq_item:last-child {
    border-bottom: 0;
    padding-bottom: 0;
  }

  .ulsanhome_badges {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 18px;
  }

  .ulsanhome_badge {
    display: inline-flex;
    align-items: center;
    padding: 8px 12px;
    border-radius: 999px;
    background: var(--ulsanhome_color_primary_soft);
    color: var(--ulsanhome_color_primary);
    border: 1px solid #d6e6f5;
    font-size: 13px;
    font-weight: 700;
  }

  .ulsanhome_hr {
    border: 0;
    border-top: 1px dashed var(--ulsanhome_color_line);
    margin: 24px 0;
  }

  .ulsanhome_small {
    font-size: 14px;
    color: var(--ulsanhome_color_muted);
  }

  .ulsanhome_em {
    color: var(--ulsanhome_color_primary);
    font-weight: 800;
  }

  @media (max-width: 768px) {
    .ulsanhome_wrap {
      padding: 10px 0 40px;
    }

    .ulsanhome_hero {
      padding: 26px 18px;
    }

    .ulsanhome_title {
      font-size: 28px;
    }

    .ulsanhome_section {
      padding: 20px 16px;
    }

    .ulsanhome_section h2 {
      font-size: 24px;
    }

    .ulsanhome_section h3 {
      font-size: 19px;
    }

    .ulsanhome_grid,
    .ulsanhome_toc,
    .ulsanhome_linkbox {
      grid-template-columns: 1fr;
    }
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;ulsanhome_wrap&quot;&gt;
&lt;div class=&quot;ulsanhome_visual&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzjfve/dJMcagdNnZy/0vAw3Ta2KKLAhPpkpAgkI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzjfve/dJMcagdNnZy/0vAw3Ta2KKLAhPpkpAgkI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzjfve/dJMcagdNnZy/0vAw3Ta2KKLAhPpkpAgkI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbzjfve%2FdJMcagdNnZy%2F0vAw3Ta2KKLAhPpkpAgkI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;section class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;울산 유홈 성안매입 정보를 다시 차분하게 정리해 보았습니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 울산에서 주거 정보를 찾다 보면 &lt;span class=&quot;ulsanhome_em&quot;&gt;유홈 성안매입&lt;/span&gt;, &lt;span class=&quot;ulsanhome_em&quot;&gt;울산도시공사 임대공고&lt;/span&gt;, 그리고 &lt;span class=&quot;ulsanhome_em&quot;&gt;울산청년정책플랫폼 U-PAGE&lt;/span&gt;를 자주 보게 됩니다. 다만 실제로 검색을 해보면 정보가 여기저기 흩어져 있고, 유홈이 정확히 어떤 브랜드인지, 이번 성안매입 공고는 어떤 성격인지, 발표는 언제쯤 나오는지 한 번에 정리된 글은 생각보다 많지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이번 글은 제가 직접 공고를 확인하고, 직접 신청도 해보면서 느낀 점까지 담아 정리해 보았습니다. 결론부터 말씀드리면, &lt;b&gt;유홈 전체 브랜드와 이번 성안매입 개별 공고는 구분해서 보는 것이 가장 정확합니다.&lt;/b&gt; 브랜드 전체는 더 넓은 범위를 담고 있고, 이번 성안매입 모집은 현재 공고 기준으로 별도의 청년임대 공고로 이해하는 편이 자연스럽습니다.&lt;/p&gt;
&lt;div class=&quot;ulsanhome_info ulsanhome_info--primary&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 최근 유홈 성안매입에 직접 신청하고 왔습니다. 현장에서 생각보다 많은 분들이 기다리고 계셔서 꽤 놀랐고, 결과는 아직 발표되지 않아 저 역시 계속 기다리고 있는 중입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulsanhome_toc&quot;&gt;&lt;a href=&quot;#ulsanhome_summary&quot;&gt;핵심 요약 먼저 보기&lt;/a&gt; &lt;a href=&quot;#ulsanhome_brand&quot;&gt;유홈 브랜드 성격 보기&lt;/a&gt; &lt;a href=&quot;#ulsanhome_sungan&quot;&gt;성안매입 공고와 발표 시기 보기&lt;/a&gt; &lt;a href=&quot;#ulsanhome_story&quot;&gt;직접 신청하고 느낀 점 보기&lt;/a&gt; &lt;a href=&quot;#ulsanhome_upage&quot;&gt;U-PAGE 활용법 보기&lt;/a&gt; &lt;a href=&quot;#ulsanhome_faq&quot;&gt;FAQ 보기&lt;/a&gt; &lt;a href=&quot;#ulsanhome_links&quot;&gt;공식 링크 바로가기&lt;/a&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_summary&quot; class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;한눈에 보는 핵심 요약&lt;/h2&gt;
&lt;div class=&quot;ulsanhome_grid&quot;&gt;
&lt;div class=&quot;ulsanhome_card&quot;&gt;&lt;b&gt;유홈 브랜드&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유홈은 울산시와 울산도시공사가 공급하는 공공주택 브랜드로 보는 편이 맞습니다. 그래서 유홈 전체를 곧바로 청년 전용 브랜드라고 단정하는 표현은 조금 조심하는 편이 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulsanhome_card&quot;&gt;&lt;b&gt;성안매입 공고&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 성안매입 모집은 공식 공고 기준으로 청년임대로 올라와 있습니다. 그래서 브랜드 전체 설명과 개별 모집 공고 설명은 나눠서 보는 것이 정확합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulsanhome_card&quot;&gt;&lt;b&gt;발표와 확인 경로&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개자료상 자격 검증 뒤 5~6월 중 최종 입주자 확정 흐름으로 안내되어 있습니다. 실제 확인은 울산도시공사 임대공고와 U-PAGE를 같이 보는 방식이 가장 효율적입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;ulsanhome_quote&quot;&gt;이번 내용을 정리하면서 가장 중요하다고 느낀 점은 하나였습니다. 유홈이라는 이름만 보고 단정하기보다, 브랜드 전체와 개별 공고를 분리해서 이해해야 정보가 훨씬 선명해진다는 점입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_brand&quot; class=&quot;ulsanhome_section&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;b&gt;이번 성안매입 개별 모집 공고&lt;/b&gt;를 구분해서 보는 것이 더 정확합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜드 차원에서 유홈은 울산시와 울산도시공사가 공급하는 공공주택의 새로운 이름으로 자리 잡아가는 흐름에 가깝습니다. 그래서 글을 쓸 때도 &amp;ldquo;유홈은 무조건 청년만을 위한 브랜드입니다&amp;rdquo;라고 단정하기보다는, &amp;ldquo;유홈은 울산 공공주택 브랜드이고, 이번 성안매입 공고는 현재 청년임대로 분류되어 있습니다&amp;rdquo;라고 설명하는 편이 훨씬 깔끔합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;최근 유홈 사례를 보면 이런 방향이 더 잘 보입니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 준공된 유홈 백합 사례를 보면 단순히 저렴한 집 한 칸을 공급하는 방식보다, 공유주방과 헬스장 같은 커뮤니티 요소를 함께 갖춘 형태로 소개되고 있습니다. 이런 흐름을 보면 유홈은 단지 임대료만 이야기하는 브랜드라기보다, 실제 거주 만족도와 생활 편의까지 함께 고려하려는 방향으로 읽히기도 합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_sungan&quot; class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;울산 유홈 성안매입 공고와 발표 시기는 이렇게 이해하시면 됩니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성안매입은 최근 울산에서 관심이 높았던 공고 중 하나였습니다. 공개된 자료를 기준으로 보면 성안동 유홈은 총 48호 규모로 공급되며, 서류 신청 이후 자격 검증을 거쳐 최종 입주자를 확정하는 흐름으로 안내되고 있습니다.&lt;/p&gt;
&lt;div class=&quot;ulsanhome_table_wrap&quot;&gt;
&lt;table class=&quot;ulsanhome_table&quot; 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;체크 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;공고 게시&lt;/td&gt;
&lt;td&gt;2026년 2월 20일&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;48호&lt;/td&gt;
&lt;td&gt;전용 19㎡형과 20㎡형 중심으로 안내됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;입주 예정&lt;/td&gt;
&lt;td&gt;2026년 6월&lt;/td&gt;
&lt;td&gt;자격 검증과 확정 절차 이후 입주 흐름으로 보시면 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;최종 확정 시기&lt;/td&gt;
&lt;td&gt;5~6월 중&lt;/td&gt;
&lt;td&gt;그래서 현장에서 들으신 5월 전후 발표 이야기와도 큰 틀에서는 맞닿아 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 분들이 가장 궁금해하시는 부분이 바로 발표 시기일 텐데, 현재 공개자료 기준으로는 &lt;b&gt;자격 검증을 거쳐 5~6월 중 최종 입주자를 확정&lt;/b&gt;하는 흐름으로 이해하는 것이 맞습니다. 그래서 아직 결과가 나오지 않은 지금 시점에서는 &amp;ldquo;발표 전&amp;rdquo;이라고 보는 것이 자연스럽고, 조금 더 기다리면서 공식 공고를 계속 확인하는 것이 가장 정확한 방법입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_story&quot; class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;저도 직접 신청해 보니 관심이 큰 이유를 조금 알 것 같았습니다&lt;/h2&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;위치가 괜찮고, 현실적으로 접근 가능한 공공임대&lt;/b&gt;에 대한 관심이 분명히 크다는 점입니다. 집은 단순히 월세 숫자만의 문제가 아니라 출근과 생활, 이동 동선, 그리고 앞으로의 안정감까지 연결되기 때문에 이런 공고 하나의 의미가 생각보다 훨씬 크게 다가오는 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 역시 아직 결과를 기다리고 있는 입장이라 더 조심스럽지만, 개인적으로는 꼭 좋은 결과가 있었으면 좋겠다는 마음입니다. 그리고 이 글을 보시는 분들께도 실제로 도움이 되는 정리였으면 좋겠습니다.&lt;/p&gt;
&lt;div class=&quot;ulsanhome_quote&quot;&gt;신청해보니 더 선명하게 느껴졌습니다. 유홈 성안매입은 단순히 한 번 스쳐 지나가는 공고가 아니라, 많은 분들이 실제로 기다리고 있던 기회에 가까웠습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_upage&quot; class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;울산청년정책플랫폼 U-PAGE는 꼭 같이 보시는 것이 좋습니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유홈 성안매입처럼 개별 공고를 볼 때 가장 먼저 확인해야 하는 곳은 물론 울산도시공사 임대공고입니다. 다만 거기서 끝내지 않고 &lt;b&gt;울산청년정책플랫폼 U-PAGE&lt;/b&gt;까지 같이 보면, 훨씬 넓은 흐름을 이해하기 쉬워집니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;U-PAGE에서 좋은 점&lt;/h3&gt;
&lt;ul class=&quot;ulsanhome_list&quot; 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;middot;문화, 참여&amp;middot;권리까지 함께 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;공고 한 건만 보는 것이 아니라 울산 정책 흐름을 넓게 파악하기 좋습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;ulsanhome_info ulsanhome_info--primary&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 기준에서는 &lt;b&gt;실제 모집 공고와 결과 확인은 울산도시공사&lt;/b&gt;에서, &lt;b&gt;추가로 챙길 수 있는 정책과 연관 지원은 U-PAGE&lt;/b&gt;에서 확인하는 방식이 가장 효율적으로 느껴졌습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 울산에 살면서 주거뿐 아니라 취업, 교육, 복지까지 함께 챙기고 싶다면 U-PAGE는 한 번쯤 꼭 들어가 볼 만한 플랫폼입니다. 한 건의 공고만 보는 것보다 정보 폭이 훨씬 넓어집니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;울산 유홈과 공공임대 정보를 볼 때 이렇게 접근하시면 더 편합니다&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 공고 원문은 울산도시공사에서 먼저 확인합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 모집 공고, 결과 공고, 첨부서류, 공고문 원문은 울산도시공사 임대공고가 기준이 됩니다. 성안매입처럼 관심이 큰 공고일수록 첨부파일까지 함께 확인해 두시는 것이 좋습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. U-PAGE로 정책 흐름을 넓게 봅니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 건의 공고만 보면 지금 열려 있는 기회만 보게 됩니다. 반면 U-PAGE는 울산 정책 안에서 주거를 포함한 다양한 지원을 같이 볼 수 있어 놓치고 있던 정보까지 챙기기에 좋습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 유홈 전체와 개별 공고를 구분해서 이해합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 성안매입은 청년임대 공고이지만, 유홈 전체 브랜드 설명은 그것보다 더 넓습니다. 그래서 검색할 때도 유홈, 성안매입, 울산도시공사 임대공고, U-PAGE를 함께 보는 편이 훨씬 정확합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_faq&quot; class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;울산 유홈 성안매입 관련 자주 묻는 질문&lt;/h2&gt;
&lt;div class=&quot;ulsanhome_faq_item&quot;&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;/div&gt;
&lt;div class=&quot;ulsanhome_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;성안매입 발표는 언제쯤으로 보면 될까요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 공개자료 기준으로는 자격 검증을 거쳐 5~6월 중 최종 입주자를 확정하는 흐름으로 안내되어 있습니다. 그래서 5월 전후 발표 이야기가 나오는 것도 큰 틀에서는 자연스럽게 이해할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulsanhome_faq_item&quot;&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;/div&gt;
&lt;div class=&quot;ulsanhome_faq_item&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;U-PAGE는 왜 같이 봐야 하나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유홈 공고 하나만 보는 것이 아니라 울산의 주거, 취업, 교육, 복지 정책을 함께 볼 수 있기 때문입니다. 실제로는 이런 플랫폼을 같이 보는 편이 훨씬 실용적입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;ulsanhome_links&quot; class=&quot;ulsanhome_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;공식 사이트 바로가기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 링크는 실제로 확인해 두면 좋은 공식 사이트입니다. 울산 유홈 성안매입 공고, 울산도시공사 임대공고, 울산청년정책플랫폼 U-PAGE를 같이 보시면 공고와 정책 흐름을 더 쉽게 연결해서 볼 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;ulsanhome_linkbox&quot;&gt;&lt;a class=&quot;ulsanhome_linkcard&quot; href=&quot;https://www.umca.co.kr/umca/bbs/view.do?bbsId=BBS_0000000000000004&amp;amp;mId=001001004000000000&amp;amp;dataId=4241&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; &lt;b&gt;유홈 성안매입 입주자 모집 공고 바로가기&lt;/b&gt; &lt;span&gt;성안매입 공고문과 첨부자료를 직접 확인할 수 있습니다.&lt;/span&gt; &lt;/a&gt; &lt;a class=&quot;ulsanhome_linkcard&quot; href=&quot;https://www.umca.co.kr/umca/bbs/list.do?bbsId=BBS_0000000000000004&amp;amp;mId=001001004000000000&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; &lt;b&gt;울산도시공사 임대공고 바로가기&lt;/b&gt; &lt;span&gt;유홈과 공공임대의 최신 모집 공고, 결과 공고 흐름을 확인할 수 있습니다.&lt;/span&gt; &lt;/a&gt; &lt;a class=&quot;ulsanhome_linkcard&quot; href=&quot;https://www.ulsan.go.kr/s/ulsanyouth/main.ulsan&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; &lt;b&gt;울산청년정책플랫폼 U-PAGE 바로가기&lt;/b&gt; &lt;span&gt;주거를 포함한 울산 정책을 조건별로 검색할 수 있습니다.&lt;/span&gt; &lt;/a&gt; &lt;a class=&quot;ulsanhome_linkcard&quot; href=&quot;https://www.ulsan.go.kr/u/rep/bbs/view.ulsan?bbsId=BBS_0000000000000027&amp;amp;dataId=179102&amp;amp;mId=001004003001000000&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; &lt;b&gt;울산시 성안동 유홈 보도자료 바로가기&lt;/b&gt; &lt;span&gt;서류 접수와 입주 예정 시기, 최종 확정 흐름을 확인할 수 있습니다.&lt;/span&gt; &lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;ulsanhome_badges&quot;&gt;&lt;span class=&quot;ulsanhome_badge&quot;&gt;#울산유홈&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#유홈성안매입&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#울산공공임대&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#울산도시공사&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#울산청년정책플랫폼&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#U_PAGE&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#울산주거정보&lt;/span&gt; &lt;span class=&quot;ulsanhome_badge&quot;&gt;#울산성안동&lt;/span&gt;&lt;/div&gt;
&lt;hr class=&quot;ulsanhome_hr&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p class=&quot;ulsanhome_small&quot; data-ke-size=&quot;size16&quot;&gt;본 글은 작성 시점 기준 공개된 공식 자료를 바탕으로 정리한 정보성 글입니다. 실제 신청 자격과 최종 발표 일정은 공식 공고문과 최신 공지를 다시 확인하시기 바랍니다.&lt;/p&gt;
&lt;/section&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine/Ulsan</category>
      <category>U-PAGE</category>
      <category>울산공공임대</category>
      <category>울산도시공사</category>
      <category>울산유홈</category>
      <category>울산주거정책</category>
      <category>울산청년플랫폼</category>
      <category>임대주택</category>
      <category>주거지원</category>
      <category>청년</category>
      <category>청년지원</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/577</guid>
      <comments>https://odinbox.tistory.com/577#entry577comment</comments>
      <pubDate>Sun, 22 Mar 2026 11:17:43 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL, Oracle DB 모니터링</title>
      <link>https://odinbox.tistory.com/576</link>
      <description>&lt;div&gt;
&lt;style&gt;
.pgocmonitoring_wrap{
  max-width:860px;
  margin:0 auto;
  padding:32px 18px 70px;
  font-family:&quot;Pretendard&quot;,&quot;Noto Sans KR&quot;,&quot;Apple SD Gothic Neo&quot;,&quot;Malgun Gothic&quot;,sans-serif;
  color:#1f2937;
  line-height:1.9;
  word-break:keep-all;
}

.pgocmonitoring_wrap *{
  box-sizing:border-box;
}

.pgocmonitoring_hero{
  padding:36px 30px;
  border:1px solid #e5e7eb;
  border-radius:24px;
  background:linear-gradient(135deg,#f8fbff 0%,#ffffff 58%,#f3f7fb 100%);
  box-shadow:0 14px 36px rgba(15,23,42,0.05);
  margin-bottom:24px;
}

.pgocmonitoring_kicker{
  display:inline-block;
  margin-bottom:14px;
  padding:6px 12px;
  border-radius:999px;
  background:#eff6ff;
  color:#1d4ed8;
  font-size:12px;
  font-weight:700;
  letter-spacing:0.04em;
}

.pgocmonitoring_title{
  margin:0;
  font-size:34px;
  line-height:1.35;
  letter-spacing:-0.03em;
  color:#111827;
  font-weight:800;
}

.pgocmonitoring_subtitle{
  margin:16px 0 0;
  font-size:17px;
  color:#4b5563;
}

.pgocmonitoring_thumb{
  margin:18px 0 30px;
  text-align:center;
}

.pgocmonitoring_thumb p{
  margin:0;
}

.pgocmonitoring_box{
  margin:24px 0;
  padding:24px;
  border:1px solid #e5e7eb;
  border-radius:20px;
  background:#ffffff;
  box-shadow:0 8px 24px rgba(15,23,42,0.04);
}

.pgocmonitoring_section{
  margin-top:56px;
}

.pgocmonitoring_h2{
  margin:0 0 18px;
  font-size:28px;
  line-height:1.42;
  letter-spacing:-0.02em;
  color:#111827;
  font-weight:800;
}

.pgocmonitoring_h3{
  margin:34px 0 14px;
  font-size:22px;
  line-height:1.48;
  letter-spacing:-0.02em;
  color:#1f2937;
  font-weight:750;
}

.pgocmonitoring_p{
  margin:0 0 18px;
  font-size:17px;
  color:#374151;
}

.pgocmonitoring_toc{
  list-style:none;
  margin:0;
  padding:0;
}

.pgocmonitoring_toc li{
  margin:10px 0;
  padding-left:0;
  font-size:16px;
  color:#374151;
}

.pgocmonitoring_toc a{
  color:#1f2937;
  text-decoration:none;
  border-bottom:1px solid rgba(31,41,55,0.15);
}

.pgocmonitoring_toc a:hover{
  color:#1d4ed8;
  border-bottom-color:rgba(29,78,216,0.3);
}

.pgocmonitoring_list{
  margin:0 0 20px;
  padding-left:22px;
}

.pgocmonitoring_list li{
  margin:10px 0;
  font-size:16px;
  color:#374151;
}

.pgocmonitoring_note{
  margin:18px 0;
  padding:16px 18px;
  border-left:4px solid #2563eb;
  border-radius:12px;
  background:#eff6ff;
  color:#1e3a8a;
  font-size:15px;
}

.pgocmonitoring_warn{
  margin:18px 0;
  padding:16px 18px;
  border-left:4px solid #dc2626;
  border-radius:12px;
  background:#fef2f2;
  color:#991b1b;
  font-size:15px;
}

.pgocmonitoring_codewrap{
  margin:20px 0 24px;
  border:1px solid #0f172a;
  border-radius:18px;
  overflow:hidden;
  background:#0b1220;
  box-shadow:0 16px 32px rgba(2,6,23,0.18);
}

.pgocmonitoring_codelabel{
  padding:13px 18px;
  background:#0f172a;
  color:#dbeafe;
  font-size:13px;
  font-weight:700;
  border-bottom:1px solid rgba(255,255,255,0.08);
}

.pgocmonitoring_code{
  margin:0;
  padding:20px 22px;
  overflow-x:auto;
  background:#0b1220;
  color:#f8fafc;
  font-size:14px;
  line-height:1.8;
  font-family:&quot;D2Coding&quot;,&quot;Consolas&quot;,&quot;Courier New&quot;,monospace;
  white-space:pre;
  tab-size:4;
}

.pgocmonitoring_tablewrap{
  overflow-x:auto;
  margin:20px 0 26px;
}

.pgocmonitoring_table{
  width:100%;
  min-width:640px;
  border-collapse:collapse;
  background:#ffffff;
  border:1px solid #e5e7eb;
  border-radius:16px;
  overflow:hidden;
}

.pgocmonitoring_table th,
.pgocmonitoring_table td{
  padding:14px 16px;
  border-bottom:1px solid #e5e7eb;
  text-align:left;
  vertical-align:top;
  font-size:15px;
  color:#374151;
}

.pgocmonitoring_table th{
  background:#f9fafb;
  color:#111827;
  font-weight:800;
}

.pgocmonitoring_table tr:last-child td{
  border-bottom:none;
}

.pgocmonitoring_divider{
  height:1px;
  margin:46px 0;
  background:linear-gradient(90deg,rgba(203,213,225,0) 0%,rgba(203,213,225,1) 50%,rgba(203,213,225,0) 100%);
}

.pgocmonitoring_tags{
  display:flex;
  flex-wrap:wrap;
  gap:10px;
  margin-top:16px;
}

.pgocmonitoring_tag{
  display:inline-flex;
  align-items:center;
  padding:8px 13px;
  border:1px solid #dbeafe;
  border-radius:999px;
  background:#f8fbff;
  color:#1d4ed8;
  font-size:13px;
  font-weight:600;
}

@media (max-width:768px){
  .pgocmonitoring_wrap{
    padding:18px 14px 44px;
  }

  .pgocmonitoring_hero,
  .pgocmonitoring_box{
    padding:22px 18px;
    border-radius:18px;
  }

  .pgocmonitoring_title{
    font-size:28px;
  }

  .pgocmonitoring_h2{
    font-size:24px;
  }

  .pgocmonitoring_h3{
    font-size:20px;
  }

  .pgocmonitoring_p,
  .pgocmonitoring_list li,
  .pgocmonitoring_toc li{
    font-size:16px;
  }

  .pgocmonitoring_code{
    font-size:13px;
    padding:18px 16px;
  }
}
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;pgocmonitoring_wrap&quot;&gt;
&lt;section class=&quot;pgocmonitoring_hero&quot;&gt;
&lt;div class=&quot;pgocmonitoring_kicker&quot;&gt;POSTGRESQL &amp;middot; ORACLE &amp;middot; DB MONITORING&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;운영 중인 시스템에서 저장 버튼이 눌렸는데 반응이 없거나, 특정 화면만 유독 느려지고, 배치 작업이 끝나지 않은 것처럼 보이는 상황을 한 번쯤은 겪게 됩니다. 이런 문제는 애플리케이션 코드만의 문제가 아니라 데이터베이스 세션 대기, 장시간 실행 쿼리, Commit 누락, Lock 충돌 때문에 발생하는 경우가 많습니다. 이번 글에서는 PostgreSQL과 Oracle 환경에서 어떤 기준으로 DB를 모니터링해야 하는지, 현재 Lock 상태를 어떻게 확인해야 하는지, 문제가 되는 세션은 어떤 방식으로 해제해야 하는지를 실무 흐름 중심으로 정리하겠습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&quot;pgocmonitoring_thumb&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crNTCr/dJMcahKssYv/S3RBQCjnoeaxoZseFmkTrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crNTCr/dJMcahKssYv/S3RBQCjnoeaxoZseFmkTrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crNTCr/dJMcahKssYv/S3RBQCjnoeaxoZseFmkTrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrNTCr%2FdJMcahKssYv%2FS3RBQCjnoeaxoZseFmkTrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;section class=&quot;pgocmonitoring_box&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h3&quot; style=&quot;margin-top: 0;&quot; data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;ul class=&quot;pgocmonitoring_toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#pgocmonitoring_sec1&quot;&gt;DB 모니터링이 왜 중요한가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pgocmonitoring_sec2&quot;&gt;PostgreSQL에서 확인해야 하는 모니터링 포인트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pgocmonitoring_sec3&quot;&gt;Oracle에서 확인해야 하는 모니터링 포인트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pgocmonitoring_sec4&quot;&gt;PostgreSQL에서 Lock 확인과 해제 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pgocmonitoring_sec5&quot;&gt;Oracle에서 Lock 확인과 해제 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pgocmonitoring_sec6&quot;&gt;운영 중 조치할 때 주의할 점&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;pgocmonitoring_sec1&quot; class=&quot;pgocmonitoring_section&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h2&quot; data-ke-size=&quot;size26&quot;&gt;DB 모니터링이 왜 중요한가&lt;/h2&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스는 서비스의 가장 안쪽에서 실제 데이터를 처리하는 핵심 계층입니다. 사용자는 웹 화면이나 프로그램 화면에서 단순히 저장, 조회, 삭제만 수행하는 것처럼 보이지만, 그 뒤에서는 세션 연결, 트랜잭션 시작, SQL 실행, Lock 획득, Commit 또는 Rollback과 같은 과정이 순차적으로 이뤄지고 있습니다.&lt;/p&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;따라서 화면이 느려지는 현상이나 저장이 멈춘 것처럼 보이는 증상은 실제로는 DB 내부에서 누군가가 자원을 오래 점유하고 있거나, 특정 세션이 다른 세션들을 대기시키고 있는 경우가 많습니다. 이런 상황을 빠르게 파악하려면 평소부터 모니터링 기준을 정리해 두고, 이상 징후가 발생했을 때 어디부터 확인할지를 알고 있어야 합니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_note&quot;&gt;운영 장애는 대부분 갑자기 발생한 것처럼 보이지만, 실제로는 이미 세션 증가, 장시간 실행 쿼리, idle in transaction, Lock 대기 같은 징후가 누적되고 있었던 경우가 많습니다.&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;실무에서 자주 보는 대표적인 징후는 아래와 같습니다.&lt;/p&gt;
&lt;ul class=&quot;pgocmonitoring_list&quot; 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;한 세션이 잡은 Lock 때문에 다른 작업들이 연쇄적으로 대기하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;결국 DB 모니터링은 단순히 수치를 보는 것이 아니라, 현재 서비스 흐름이 정상적으로 돌고 있는지 확인하는 운영 기술이라고 볼 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;pgocmonitoring_sec2&quot; class=&quot;pgocmonitoring_section&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h2&quot; data-ke-size=&quot;size26&quot;&gt;PostgreSQL에서 확인해야 하는 모니터링 포인트&lt;/h2&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL에서는 기본적으로 제공되는 시스템 뷰만 잘 활용해도 많은 문제를 추적할 수 있습니다. 가장 대표적인 대상은 pg_stat_activity와 pg_locks입니다. pg_stat_activity는 현재 살아 있는 세션과 실행 중인 쿼리 상태를 보여주고, pg_locks는 어떤 Lock이 어떤 세션에 의해 점유되고 있는지를 보여줍니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;현재 실행 중인 세션과 SQL 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;문제 상황이 발생하면 가장 먼저 현재 어떤 세션이 살아 있는지를 확인해야 합니다. 특히 state가 idle이 아닌 세션, query_start 이후 오래 실행되고 있는 세션, wait_event가 표시되는 세션은 우선적으로 볼 필요가 있습니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;PostgreSQL &amp;middot; active session 확인&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT
    pid,
    usename,
    application_name,
    client_addr,
    state,
    wait_event_type,
    wait_event,
    now() - query_start AS duration,
    query
FROM pg_stat_activity
WHERE state &amp;lt;&amp;gt; 'idle'
ORDER BY query_start;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;위 결과에서 특히 확인할 것은 아래와 같습니다.&lt;/p&gt;
&lt;ul class=&quot;pgocmonitoring_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;duration 값이 비정상적으로 긴 세션이 있는지&lt;/li&gt;
&lt;li&gt;state가 active인지, idle in transaction인지&lt;/li&gt;
&lt;li&gt;wait_event_type과 wait_event가 무엇인지&lt;/li&gt;
&lt;li&gt;어떤 application_name으로 접속했는지&lt;/li&gt;
&lt;li&gt;어떤 SQL이 반복적으로 오래 수행되고 있는지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;Lock 상태 상세 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;세션 상태만 보는 것으로 부족할 때는 pg_locks와 pg_stat_activity를 같이 조회하여 어떤 Lock 타입이 걸려 있는지, 실제로 granted 상태인지, 기다리는 중인지까지 확인할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;PostgreSQL &amp;middot; lock 상세 조회&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT
    a.pid,
    a.usename,
    a.application_name,
    a.state,
    a.wait_event_type,
    a.wait_event,
    l.locktype,
    l.mode,
    l.granted,
    a.query
FROM pg_locks l
JOIN pg_stat_activity a
  ON l.pid = a.pid
ORDER BY a.pid, l.granted, l.locktype;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;granted 값이 false인 경우는 해당 Lock을 아직 획득하지 못하고 대기 중이라는 의미입니다. 이 결과를 통해 단순히 느린 쿼리인지, 아니면 자원 대기 때문인지 구분하는 데 도움이 됩니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;pgocmonitoring_sec3&quot; class=&quot;pgocmonitoring_section&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h2&quot; data-ke-size=&quot;size26&quot;&gt;Oracle에서 확인해야 하는 모니터링 포인트&lt;/h2&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Oracle은 PostgreSQL과 유사한 문제를 다른 뷰를 통해 확인합니다. 대표적으로 V$SESSION, V$SQL, V$LOCK가 자주 사용됩니다. 현재 어떤 세션이 살아 있는지, 어떤 SQL을 수행 중인지, 어떤 세션이 다른 세션을 막고 있는지를 순서대로 보는 것이 일반적입니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;현재 세션과 실행 SQL 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Oracle에서는 현재 접속 세션, 프로그램 이름, 접속 장비, SQL_ID 등을 함께 보는 것이 좋습니다. 이 정보가 있어야 실제 사용자 작업인지, 특정 인터페이스 프로그램인지, 배치 작업인지 구분할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;Oracle &amp;middot; session 및 SQL 확인&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code sql&quot;&gt;&lt;code&gt;SELECT
    s.sid,
    s.serial#,
    s.username,
    s.status,
    s.machine,
    s.program,
    s.sql_id,
    q.sql_text
FROM v$session s
LEFT JOIN v$sql q
  ON s.sql_id = q.sql_id
WHERE s.username IS NOT NULL
ORDER BY s.logon_time DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;결과를 볼 때는 아래 항목을 같이 확인하면 좋습니다.&lt;/p&gt;
&lt;ul class=&quot;pgocmonitoring_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동일 machine 또는 program에서 세션이 과도하게 많은지&lt;/li&gt;
&lt;li&gt;같은 SQL_ID가 반복적으로 오래 남아 있는지&lt;/li&gt;
&lt;li&gt;특정 사용자나 특정 인터페이스에서만 문제가 집중되는지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;대기 세션과 blocking session 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Oracle에서는 blocking_session 컬럼을 통해 현재 어떤 세션이 다른 세션을 막고 있는지 확인할 수 있습니다. seconds_in_wait가 길다면 이미 사용자는 저장 지연이나 화면 멈춤을 체감하고 있을 가능성이 큽니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;Oracle &amp;middot; blocking session 확인&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code sql&quot;&gt;&lt;code&gt;SELECT
    sid,
    serial#,
    username,
    blocking_session,
    event,
    wait_class,
    seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL
ORDER BY seconds_in_wait DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pgocmonitoring_sec4&quot; class=&quot;pgocmonitoring_section&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h2&quot; data-ke-size=&quot;size26&quot;&gt;PostgreSQL에서 Lock 확인과 해제 방법&lt;/h2&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL에서 Lock 문제를 볼 때 핵심은 누가 기다리고 있는지가 아니라, 실제로 누가 Lock을 잡고 있는지를 찾는 것입니다. blocked 세션보다 blocking 세션이 원인인 경우가 대부분이기 때문입니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;현재 막히고 있는 세션 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;pg_blocking_pids() 함수는 특정 세션을 막고 있는 PID 목록을 반환합니다. 이를 이용하면 현재 대기 상태에 있는 세션을 빠르게 골라낼 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;PostgreSQL &amp;middot; blocking PID 확인&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT
    pid,
    usename,
    application_name,
    wait_event_type,
    wait_event,
    pg_blocking_pids(pid) AS blocking_pids,
    query
FROM pg_stat_activity
WHERE cardinality(pg_blocking_pids(pid)) &amp;gt; 0;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;blocked 세션과 blocking 세션을 함께 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;운영에서는 단순히 PID 하나만 보는 것보다, 누가 대기 중이고 누가 막고 있는지를 한 화면에서 같이 보는 것이 훨씬 편합니다. 아래 쿼리는 blocked 세션과 blocking 세션을 함께 보여주는 예시입니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;PostgreSQL &amp;middot; blocked / blocking 관계 확인&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT
    blocked.pid AS blocked_pid,
    blocked.usename AS blocked_user,
    blocked.query AS blocked_query,
    blocking.pid AS blocking_pid,
    blocking.usename AS blocking_user,
    blocking.query AS blocking_query
FROM pg_stat_activity blocked
JOIN pg_stat_activity blocking
  ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;이 결과를 보면 실제 원인이 되는 세션이 어떤 SQL을 수행 중인지 비교적 쉽게 파악할 수 있습니다. 저장 버튼이 안 눌리는 사용자 쪽 세션보다, 먼저 Lock을 잡고 오래 유지한 세션이 더 중요합니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;먼저 쿼리만 취소하는 방법&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL에서는 바로 세션을 죽이기 전에 현재 실행 중인 쿼리만 취소할 수 있습니다. 장시간 조회 SQL이나 단순히 오래 걸리는 작업이라면 이 방법을 먼저 검토하는 편이 안전합니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;PostgreSQL &amp;middot; 쿼리 취소&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT pg_cancel_backend(12345);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;위 예시에서 12345는 종료 대상 PID입니다. 이 방법은 현재 실행 중인 SQL만 취소하고 세션 자체는 유지합니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;세션 자체를 종료하는 방법&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Commit 누락, idle in transaction 상태 장기 유지, 비정상 세션 유지처럼 명확히 문제를 일으키는 세션이라면 세션 종료를 검토할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;PostgreSQL &amp;middot; 세션 종료&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT pg_terminate_backend(12345);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;pgocmonitoring_tablewrap&quot;&gt;
&lt;table class=&quot;pgocmonitoring_table&quot; 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;권장 상황&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;pg_cancel_backend&lt;/td&gt;
&lt;td&gt;실행 중인 쿼리만 취소합니다.&lt;/td&gt;
&lt;td&gt;장시간 조회, 일시적 지연, 취소 가능한 SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pg_terminate_backend&lt;/td&gt;
&lt;td&gt;세션 자체를 강제로 종료합니다.&lt;/td&gt;
&lt;td&gt;Commit 누락, 장기 Lock 점유, 비정상 세션&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;pgocmonitoring_warn&quot;&gt;운영 환경에서는 세션 종료 전에 반드시 해당 세션이 어떤 사용자 작업인지, 어떤 프로그램에서 발생한 것인지, 종료했을 때 다른 후속 작업에 영향은 없는지 확인하는 것이 좋습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pgocmonitoring_sec5&quot; class=&quot;pgocmonitoring_section&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h2&quot; data-ke-size=&quot;size26&quot;&gt;Oracle에서 Lock 확인과 해제 방법&lt;/h2&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Oracle에서도 접근 방식은 같습니다. 기다리는 세션보다 막고 있는 세션을 찾고, 해당 세션이 실제로 어떤 작업을 수행 중인지 확인한 뒤, 필요할 경우 세션 종료를 검토합니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;Lock 대기 세션 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;먼저 현재 대기 중인 세션을 확인합니다. blocking_session 값이 있다는 것은 현재 다른 세션 때문에 기다리고 있다는 의미입니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;Oracle &amp;middot; lock 대기 세션 확인&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code sql&quot;&gt;&lt;code&gt;SELECT
    sid,
    serial#,
    username,
    blocking_session,
    event,
    wait_class,
    seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL
ORDER BY seconds_in_wait DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;Lock 보유 세션 상세 확인&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;더 자세하게 보고 싶다면 V$LOCK와 V$SESSION을 조합하여 어떤 세션이 어떤 형태의 Lock을 오래 유지하고 있는지 확인할 수 있습니다. 이 단계에서는 단순히 기다리는 쪽이 아니라 실제 Lock을 보유한 쪽의 지속 시간과 상태를 확인하는 것이 중요합니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;Oracle &amp;middot; lock 보유 세션 상세 조회&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code pgsql&quot;&gt;&lt;code&gt;SELECT
    s.sid,
    s.serial#,
    s.username,
    l.type,
    l.id1,
    l.id2,
    l.lmode,
    l.request,
    l.ctime
FROM v$lock l
JOIN v$session s
  ON l.sid = s.sid
ORDER BY l.ctime DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;ctime 값은 해당 Lock이 얼마나 오래 유지되고 있는지 확인하는 데 도움이 됩니다. 동일 사용자나 동일 프로그램에서 지속적으로 오래 잡히는 패턴이 있다면 트랜잭션 구조 자체를 다시 점검할 필요가 있습니다.&lt;/p&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;문제 세션 종료 방법&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Oracle에서는 일반적으로 문제 세션을 확인한 뒤 ALTER SYSTEM KILL SESSION 명령으로 종료를 수행합니다. 이때는 SID와 SERIAL 값을 함께 사용해야 합니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_codewrap&quot;&gt;
&lt;div class=&quot;pgocmonitoring_codelabel&quot;&gt;Oracle &amp;middot; 세션 종료&lt;/div&gt;
&lt;pre class=&quot;pgocmonitoring_code routeros&quot;&gt;&lt;code&gt;ALTER SYSTEM KILL SESSION '123,4567';&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;여기서 123은 SID이고 4567은 SERIAL 값입니다. 보통 V$SESSION 조회 결과를 바탕으로 실제 종료 대상을 결정합니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_note&quot;&gt;Oracle은 kill 명령을 내려도 세션이 즉시 완전히 사라지지 않을 수 있습니다. 롤백이 진행 중이거나 내부 정리 작업이 남아 있는 경우에는 KILLED 상태로 일정 시간 유지될 수 있습니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pgocmonitoring_sec6&quot; class=&quot;pgocmonitoring_section&quot;&gt;
&lt;h2 class=&quot;pgocmonitoring_h2&quot; data-ke-size=&quot;size26&quot;&gt;운영 중 조치할 때 주의할 점&lt;/h2&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;Lock 문제를 푸는 것은 단순히 세션을 끊는 작업이 아닙니다. 왜 그 세션이 오래 살아 있었는지, 왜 Commit이 되지 않았는지, 왜 같은 시간대에 반복되는지를 함께 봐야 재발을 줄일 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;특히 운영 환경에서는 사용자의 실제 업무가 진행 중일 수 있고, 배치나 인터페이스와 연결된 세션일 수도 있기 때문에 조치 순서를 명확히 가져가는 것이 중요합니다.&lt;/p&gt;
&lt;ul class=&quot;pgocmonitoring_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;먼저 blocked 세션보다 blocking 세션을 정확히 찾습니다.&lt;/li&gt;
&lt;li&gt;해당 세션이 화면 작업인지, 배치인지, 인터페이스인지 구분합니다.&lt;/li&gt;
&lt;li&gt;PostgreSQL은 가능하면 cancel부터 검토하고, 필요 시 terminate로 넘어갑니다.&lt;/li&gt;
&lt;li&gt;Oracle은 kill 이후에도 롤백 및 정리 시간이 필요할 수 있다는 점을 고려합니다.&lt;/li&gt;
&lt;li&gt;반복되는 경우 SQL 구조, 인덱스, 트랜잭션 범위, Commit 시점을 점검해야 합니다.&lt;/li&gt;
&lt;li&gt;idle in transaction 상태가 자주 발생한다면 애플리케이션 예외 처리 흐름도 함께 확인해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;pgocmonitoring_warn&quot;&gt;가장 위험한 조치는 원인 파악 없이 세션을 무조건 종료하는 것입니다. 일시적으로 증상이 사라질 수는 있지만, 데이터 정합성 문제나 후속 장애를 더 크게 만들 수 있습니다.&lt;/div&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL과 Oracle 모두 기본 제공 시스템 뷰만 잘 활용해도 현재 세션 상태, 장시간 실행 쿼리, Lock 대기 관계를 충분히 파악할 수 있습니다. 운영 환경에서는 장애가 발생한 뒤 당황해서 하나씩 찾기보다, 평소에 자주 보는 조회 SQL과 판단 기준을 정리해 두는 것이 훨씬 중요합니다.&lt;/p&gt;
&lt;p class=&quot;pgocmonitoring_p&quot; data-ke-size=&quot;size16&quot;&gt;결국 핵심은 단순합니다. 누가 살아 있는지 보고, 누가 막고 있는지 찾고, 어떤 조치가 가장 안전한지 판단하는 흐름을 익혀두는 것입니다. 이 흐름이 정리되어 있으면 DB 장애 대응 속도와 정확도는 확실히 달라집니다.&lt;/p&gt;
&lt;div class=&quot;pgocmonitoring_divider&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3 class=&quot;pgocmonitoring_h3&quot; data-ke-size=&quot;size23&quot;&gt;태그&lt;/h3&gt;
&lt;div class=&quot;pgocmonitoring_tags&quot;&gt;&lt;span class=&quot;pgocmonitoring_tag&quot;&gt;PostgreSQL&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;Oracle&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;DB모니터링&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;DB Lock&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;트랜잭션&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;세션관리&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;운영장애&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;SQL운영&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;개발자실무&lt;/span&gt; &lt;span class=&quot;pgocmonitoring_tag&quot;&gt;데이터베이스&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>Database</category>
      <category>DB</category>
      <category>DBLOCK</category>
      <category>DB모니터링</category>
      <category>Oracle</category>
      <category>PostgreSQL</category>
      <category>개발</category>
      <category>데이터베이스모니터링</category>
      <category>데이터베이스운영</category>
      <category>트랜잭션관리</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/576</guid>
      <comments>https://odinbox.tistory.com/576#entry576comment</comments>
      <pubDate>Sun, 15 Mar 2026 19:09:09 +0900</pubDate>
    </item>
    <item>
      <title>갤럭시 버즈4 프로 리뷰, Hi-Fi 사운드, 초광대역 통화, Galaxy AI까지 직접 써본 후기</title>
      <link>https://odinbox.tistory.com/575</link>
      <description>&lt;div&gt;
&lt;style&gt;
:root{
  --samsungbuds_bg:#f5f8fc;
  --samsungbuds_surface:#ffffff;
  --samsungbuds_surface_alt:#f8fbff;
  --samsungbuds_text:#111827;
  --samsungbuds_text_soft:#4b5563;
  --samsungbuds_text_muted:#6b7280;
  --samsungbuds_line:#dbe5f0;
  --samsungbuds_line_soft:#e9eff7;
  --samsungbuds_brand:#0f172a;
  --samsungbuds_accent:#3559d8;
  --samsungbuds_accent_soft:#edf3ff;
  --samsungbuds_shadow:0 18px 40px rgba(15,23,42,.08);
  --samsungbuds_shadow_soft:0 10px 24px rgba(15,23,42,.05);
  --samsungbuds_radius_xl:30px;
  --samsungbuds_radius_lg:22px;
  --samsungbuds_radius_md:16px;
  --samsungbuds_radius_sm:12px;
  --samsungbuds_maxw:980px;
  --samsungbuds_font:-apple-system,BlinkMacSystemFont,&quot;Segoe UI&quot;,&quot;Apple SD Gothic Neo&quot;,&quot;Malgun Gothic&quot;,&quot;Noto Sans KR&quot;,sans-serif;
}

.samsungbuds_wrap,
.samsungbuds_wrap *{
  box-sizing:border-box;
}

.samsungbuds_wrap{
  max-width:var(--samsungbuds_maxw);
  margin:0 auto;
  padding:28px 18px 70px;
  color:var(--samsungbuds_text);
  font-family:var(--samsungbuds_font);
  line-height:1.84;
  word-break:keep-all;
  background:linear-gradient(180deg,#f5f8fc 0%,#ffffff 18%,#f7fafe 100%);
}

.samsungbuds_wrap img{
  display:block;
  max-width:100%;
  height:auto;
  border-radius:18px;
}

.samsungbuds_hero{
  position:relative;
  overflow:hidden;
  margin-bottom:28px;
  padding:34px 26px 30px;
  border:1px solid #d8e3f1;
  border-radius:32px;
  background:
    radial-gradient(circle at top right, rgba(53,89,216,.12) 0, rgba(53,89,216,0) 34%),
    radial-gradient(circle at bottom left, rgba(83,110,255,.08) 0, rgba(83,110,255,0) 28%),
    linear-gradient(135deg,#fbfdff 0%,#ffffff 56%,#eef4ff 100%);
  box-shadow:var(--samsungbuds_shadow);
}

.samsungbuds_hero_badges{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
  margin-bottom:16px;
}

.samsungbuds_badge{
  display:inline-flex;
  align-items:center;
  padding:6px 12px;
  border:1px solid #d9e4f4;
  border-radius:999px;
  background:rgba(255,255,255,.92);
  color:#2641a8;
  font-size:12px;
  font-weight:700;
  letter-spacing:.02em;
}

.samsungbuds_title{
  margin:0 0 14px;
  font-size:34px;
  line-height:1.28;
  letter-spacing:-0.03em;
  color:var(--samsungbuds_brand);
  font-weight:900;
}

.samsungbuds_subtitle{
  margin:0;
  font-size:16px;
  color:var(--samsungbuds_text_soft);
}

.samsungbuds_meta{
  display:flex;
  flex-wrap:wrap;
  gap:10px 18px;
  margin-top:18px;
  padding-top:16px;
  border-top:1px solid rgba(148,163,184,.22);
  color:var(--samsungbuds_text_muted);
  font-size:13px;
}

.samsungbuds_lead{
  margin:0 0 30px;
  padding:22px 22px 24px;
  border:1px solid #dde7f3;
  border-radius:22px;
  background:#fff;
  box-shadow:var(--samsungbuds_shadow_soft);
}

.samsungbuds_lead p{
  margin:0;
  font-size:17px;
  color:#1f2937;
}

.samsungbuds_toc{
  margin:0 0 32px;
  padding:24px;
  border:1px solid var(--samsungbuds_line);
  border-radius:24px;
  background:linear-gradient(180deg,#ffffff 0%,#f8fbff 100%);
}

.samsungbuds_toc_title{
  margin:0 0 14px;
  font-size:16px;
  font-weight:800;
  color:var(--samsungbuds_brand);
}

.samsungbuds_toc_list{
  margin:0;
  padding:0;
  list-style:none;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:10px 14px;
}

.samsungbuds_toc_list li{
  margin:0;
}

.samsungbuds_toc_list a{
  display:block;
  padding:11px 13px;
  border:1px solid #e5edf7;
  border-radius:12px;
  background:#fff;
  text-decoration:none;
  color:#1f2937;
  font-size:14px;
  transition:all .2s ease;
}

.samsungbuds_toc_list a:hover{
  background:#f4f8ff;
  border-color:#cedcf7;
}

.samsungbuds_section{
  margin:0 0 28px;
  padding:28px 24px;
  border:1px solid var(--samsungbuds_line);
  border-radius:26px;
  background:var(--samsungbuds_surface);
  box-shadow:var(--samsungbuds_shadow_soft);
}

.samsungbuds_section_title{
  margin:0 0 18px;
  font-size:28px;
  line-height:1.35;
  letter-spacing:-0.025em;
  color:var(--samsungbuds_brand);
  font-weight:900;
}

.samsungbuds_section p{
  margin:0 0 16px;
  color:#1f2937;
  font-size:16px;
}

.samsungbuds_section p:last-child{
  margin-bottom:0;
}

.samsungbuds_photo_grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:16px;
  margin:18px 0 20px;
}

.samsungbuds_photo_item{
  margin:0;
}

.samsungbuds_photo_item p{
  margin:0 !important;
}

.samsungbuds_single_photo{
  margin:18px 0 20px;
}

.samsungbuds_caption{
  margin-top:10px;
  padding:10px 12px;
  border:1px solid var(--samsungbuds_line_soft);
  border-radius:12px;
  background:#f8fafc;
  font-size:13px;
  color:#5b6578;
}

.samsungbuds_quote{
  margin:22px 0;
  padding:22px 22px 22px 24px;
  border-left:5px solid var(--samsungbuds_accent);
  border-radius:18px;
  background:linear-gradient(180deg,#f8fbff 0%,#eef4ff 100%);
}

.samsungbuds_quote p{
  margin:0;
  font-size:18px;
  font-weight:800;
  line-height:1.65;
  color:#0f172a;
}

.samsungbuds_split{
  display:grid;
  grid-template-columns:1.15fr .85fr;
  gap:18px;
  margin:18px 0 8px;
}

.samsungbuds_card{
  padding:20px 18px;
  border:1px solid var(--samsungbuds_line);
  border-radius:18px;
  background:var(--samsungbuds_surface_alt);
}

.samsungbuds_card h4{
  margin:0 0 10px;
  font-size:17px;
  color:var(--samsungbuds_brand);
  font-weight:800;
}

.samsungbuds_card p{
  margin:0;
  font-size:15px;
  color:var(--samsungbuds_text_soft);
}

.samsungbuds_keypoints{
  display:grid;
  gap:10px;
  margin:18px 0 0;
  padding:0;
  list-style:none;
}

.samsungbuds_keypoints li{
  position:relative;
  margin:0;
  padding:12px 14px 12px 40px;
  border:1px solid #e4ebf5;
  border-radius:14px;
  background:#fff;
  color:#1f2937;
  font-size:15px;
}

.samsungbuds_keypoints li:before{
  content:&quot;✓&quot;;
  position:absolute;
  left:14px;
  top:10px;
  display:flex;
  align-items:center;
  justify-content:center;
  width:18px;
  height:18px;
  border-radius:999px;
  background:#e9f1ff;
  color:#1d4ed8;
  font-size:12px;
  font-weight:900;
}

.samsungbuds_table_wrap{
  margin:18px 0 0;
  overflow-x:auto;
  border:1px solid var(--samsungbuds_line);
  border-radius:18px;
  background:#fff;
}

table.samsungbuds_table{
  width:100%;
  min-width:760px;
  border-collapse:collapse;
  font-size:14px;
}

table.samsungbuds_table thead th{
  padding:14px;
  background:#0f172a;
  color:#fff;
  text-align:left;
  font-weight:800;
  vertical-align:top;
  border-right:1px solid rgba(255,255,255,.12);
}

table.samsungbuds_table tbody td{
  padding:14px;
  border-top:1px solid #e5ebf3;
  border-right:1px solid #eef3f8;
  color:#1f2937;
  vertical-align:top;
  line-height:1.7;
}

table.samsungbuds_table tbody tr:nth-child(even){
  background:#f9fbfe;
}

table.samsungbuds_table th:last-child,
table.samsungbuds_table td:last-child{
  border-right:none;
}

.samsungbuds_note{
  margin-top:14px;
  padding:15px 16px;
  border:1px solid #f3dfb4;
  border-radius:14px;
  background:#fff8eb;
  color:#7c5a10;
  font-size:14px;
}

.samsungbuds_summary{
  margin-top:12px;
  padding:24px 22px;
  border:1px solid #d7e4f6;
  border-radius:22px;
  background:
    radial-gradient(circle at right top, rgba(37,99,235,.09) 0, rgba(37,99,235,0) 28%),
    linear-gradient(180deg,#ffffff 0%,#f5f9ff 100%);
}

.samsungbuds_summary h3{
  margin:0 0 12px;
  font-size:22px;
  color:var(--samsungbuds_brand);
  font-weight:900;
}

.samsungbuds_summary p{
  margin:0 0 12px;
}

.samsungbuds_summary p:last-child{
  margin-bottom:0;
}

.samsungbuds_tags{
  margin-top:26px;
  padding:20px 22px;
  border:1px solid var(--samsungbuds_line);
  border-radius:20px;
  background:#fff;
}

.samsungbuds_tags_title{
  margin:0 0 12px;
  font-size:15px;
  font-weight:800;
  color:var(--samsungbuds_brand);
}

.samsungbuds_tag_list{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
}

.samsungbuds_tag{
  display:inline-flex;
  align-items:center;
  padding:8px 12px;
  border:1px solid #dde7f4;
  border-radius:999px;
  background:#f1f5fb;
  color:#334155;
  font-size:13px;
  font-weight:700;
}

.samsungbuds_footer{
  margin-top:28px;
  padding:22px 20px;
  text-align:center;
  color:#64748b;
  font-size:13px;
}

@media (max-width:900px){
  .samsungbuds_split{
    grid-template-columns:1fr;
  }
  .samsungbuds_toc_list,
  .samsungbuds_photo_grid{
    grid-template-columns:1fr;
  }
}

@media (max-width:720px){
  .samsungbuds_wrap{
    padding:18px 12px 54px;
  }
  .samsungbuds_hero{
    padding:24px 18px 20px;
    border-radius:24px;
  }
  .samsungbuds_title{
    font-size:26px;
  }
  .samsungbuds_section{
    padding:22px 16px;
    border-radius:20px;
  }
  .samsungbuds_section_title{
    font-size:22px;
  }
}
&lt;/style&gt;
&lt;/div&gt;
&lt;div id=&quot;samsungbuds_wrap&quot; class=&quot;samsungbuds_wrap&quot;&gt;
&lt;section class=&quot;samsungbuds_hero&quot;&gt;
&lt;div class=&quot;samsungbuds_hero_badges&quot;&gt;&lt;br /&gt;&lt;span class=&quot;samsungbuds_badge&quot;&gt;프리미엄 무선이어폰 리뷰&lt;/span&gt;&lt;/div&gt;
&lt;h1 class=&quot;samsungbuds_title&quot;&gt;갤럭시 버즈4 프로 리뷰 : Hi-Fi 사운드, 초광대역 통화, Galaxy AI까지 직접 써본 후기&lt;/h1&gt;
&lt;p class=&quot;samsungbuds_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;갤럭시 버즈4 프로를 직접 개봉하고 사용해보며 디자인, 음질, 통화 품질, 착용감, Galaxy AI 경험까지 정리한 이벤트 참여형 실사용 리뷰입니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_meta&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt; &lt;span&gt;키워드 : 갤럭시 버즈4 프로 리뷰, 음질, 통화 품질, Galaxy AI, 착용감&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;div class=&quot;samsungbuds_single_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pnkEE/dJMcachZdEJ/ku98SLC61mCfWd7w0vkUX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pnkEE/dJMcachZdEJ/ku98SLC61mCfWd7w0vkUX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pnkEE/dJMcachZdEJ/ku98SLC61mCfWd7w0vkUX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpnkEE%2FdJMcachZdEJ%2Fku98SLC61mCfWd7w0vkUX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;section class=&quot;samsungbuds_lead&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 삼성전자 갤럭시 버즈4 | 버즈4 프로 리뷰어 이벤트 참여를 계기로 작성한 사용 후기입니다. 무선이어폰은 이제 단순히 음악만 듣는 제품이 아니라, 통화와 이동 중 제어, AI 기능 활용, 장시간 착용감까지 함께 봐야 하는 시대가 되었습니다. 그래서 이번에는 단순 스펙 나열보다 실제로 얼마나 자주 손이 가는지, 그리고 일상 속에서 어떤 부분이 좋게 느껴졌는지를 중심으로 정리해보았습니다. 결론부터 말하면, 보기보다 더 야무진 제품이었습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;samsungbuds_toc&quot;&gt;
&lt;h3 class=&quot;samsungbuds_toc_title&quot; data-ke-size=&quot;size23&quot;&gt;목차&lt;/h3&gt;
&lt;ul class=&quot;samsungbuds_toc_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_intro&quot;&gt;갤럭시 버즈4 프로를 기대한 이유&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_sec1&quot;&gt;개봉기와 패키지 구성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_sec2&quot;&gt;디자인과 외관 디테일&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_sec3&quot;&gt;케이스 구조와 충전 편의성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_sec4&quot;&gt;Hi-Fi 사운드 사용 후기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_sec5&quot;&gt;초광대역 통화와 Galaxy AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_sec6&quot;&gt;착용감과 이벤트 참여 관점 총평&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samsungbuds_outro&quot;&gt;추천 포인트 정리&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_intro&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;갤럭시 버즈4 프로를 기대한 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갤럭시 버즈4 프로는 단순히 &amp;ldquo;새로 나온 삼성 무선이어폰&amp;rdquo; 정도로 끝나는 제품이 아니라, 실제 사용 기준에서 음질과 통화 품질, Galaxy AI 활용성, 그리고 착용감까지 두루 기대하게 만드는 제품이었습니다. 특히 이번 리뷰어 미션에서도 Hi-Fi 사운드, 초광대역 통화, AI 기능, 착용감이 핵심 포인트로 제시된 만큼, 단순한 첫인상보다 실사용 중심으로 보는 게 더 중요하다고 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명 : 무선이어폰은 결국 스펙표보다 &amp;lsquo;하루 동안 몇 번이나 자연스럽게 손이 가는가&amp;rsquo;가 더 중요합니다. 그런 의미에서 갤럭시 버즈4 프로는 꽤 기대를 갖고 보게 되는 제품이었습니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_quote&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;사진으로 예뻐 보이는 제품&amp;rdquo;과 &amp;ldquo;실제로 자주 쓰게 되는 제품&amp;rdquo;은 다를 때가 많은데, 이번에는 둘 다 어느 정도 챙긴 느낌이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_sec1&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;개봉기와 패키지 구성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 개봉 단계에서는 제품 박스부터 구성품, 본체 첫인상까지 차근차근 살펴보았습니다. 패키지는 전체적으로 군더더기 없이 정리된 느낌이었고, 플래그십 라인업답게 깔끔하고 단정한 인상이 강했습니다. 과장된 화려함보다는, 실제 제품 자체에 집중하게 만드는 방향이었습니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_photo_grid&quot;&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;
&lt;div class=&quot;samsungbuds_caption&quot;&gt;버즈4 프로 개봉 직후 모습 : 처음 상자를 열었을 때 보이는 제품 배치와 전반적인 첫인상을 확인할 수 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HcVfh/dJMcagLsVRv/V61QPF7yoh5xyL1ynSwfh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HcVfh/dJMcagLsVRv/V61QPF7yoh5xyL1ynSwfh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HcVfh/dJMcagLsVRv/V61QPF7yoh5xyL1ynSwfh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHcVfh%2FdJMcagLsVRv%2FV61QPF7yoh5xyL1ynSwfh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;제품 박스 뒷면 : 주요 정보와 패키지 구성을 확인할 수 있는 뒷면 사진입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_grid&quot;&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t1htS/dJMcagSd3wQ/NMbW4VlwcoKPn0auHqs6M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t1htS/dJMcagSd3wQ/NMbW4VlwcoKPn0auHqs6M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t1htS/dJMcagSd3wQ/NMbW4VlwcoKPn0auHqs6M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft1htS%2FdJMcagSd3wQ%2FNMbW4VlwcoKPn0auHqs6M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;제품 옆면 1 : 패키지의 측면 구성과 박스 외형을 확인할 수 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLml81/dJMcadVrIJ5/hM4HMUyQKn0951B7ytkGu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLml81/dJMcadVrIJ5/hM4HMUyQKn0951B7ytkGu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLml81/dJMcadVrIJ5/hM4HMUyQKn0951B7ytkGu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLml81%2FdJMcadVrIJ5%2FhM4HMUyQKn0951B7ytkGu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;제품 옆면 2 : 박스 측면 디테일을 보다 자세히 볼 수 있는 사진입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_grid&quot;&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ce4J6L/dJMcagLsVFL/VtcsZFSKJYHi2ji1pNfIiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ce4J6L/dJMcagLsVFL/VtcsZFSKJYHi2ji1pNfIiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ce4J6L/dJMcagLsVFL/VtcsZFSKJYHi2ji1pNfIiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fce4J6L%2FdJMcagLsVFL%2FVtcsZFSKJYHi2ji1pNfIiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;제품 옆면 3 : 패키지 외형을 마저 확인할 수 있는 마지막 측면 컷입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZhG1R/dJMcaiibC9h/wTv7R7wqNmzEmgL2cCN9W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZhG1R/dJMcaiibC9h/wTv7R7wqNmzEmgL2cCN9W0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZhG1R/dJMcaiibC9h/wTv7R7wqNmzEmgL2cCN9W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZhG1R%2FdJMcaiibC9h%2FwTv7R7wqNmzEmgL2cCN9W0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;구성품 사진 1 : 이어팁, 설명서, 본체까지 전체 구성품을 한눈에 볼 수 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_single_photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9Wre0/dJMcaiibC9k/8vWm7Pc8QrazhEe2YZNBjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9Wre0/dJMcaiibC9k/8vWm7Pc8QrazhEe2YZNBjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9Wre0/dJMcaiibC9k/8vWm7Pc8QrazhEe2YZNBjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9Wre0%2FdJMcaiibC9k%2F8vWm7Pc8QrazhEe2YZNBjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;구성품 사진 2 : 이어팁, 설명서, 본체 구성을 다른 각도에서 확인할 수 있는 사진입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성품은 필요한 요소만 간결하게 들어 있어 깔끔했습니다. 이어팁과 설명서, 본체 중심으로 정리되어 있었고, 개봉 직후의 인상도 과하게 요란하기보다는 잘 정돈된 느낌이 강했습니다. 솔직히 개봉할 때만큼은 누구나 잠깐 리뷰어가 되는데, 이 제품은 그 순간의 만족감이 꽤 괜찮았습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_sec2&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;디자인과 외관 디테일&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품 외관은 실제로 손에 쥐고 봤을 때 더 괜찮게 느껴졌습니다. 특히 케이스와 이어버드 본체의 디테일, 마감, 로고 처리 같은 부분이 사진보다 실물에서 더 자연스럽게 다가왔습니다. 이런 요소는 화려하게 튀지는 않지만, 오래 볼수록 잘 정리되었다는 인상을 남깁니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_photo_grid&quot;&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CrqyH/dJMcagLsVRx/eK7ZzMv5hHqL06Hn6JIhn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CrqyH/dJMcagLsVRx/eK7ZzMv5hHqL06Hn6JIhn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CrqyH/dJMcagLsVRx/eK7ZzMv5hHqL06Hn6JIhn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCrqyH%2FdJMcagLsVRx%2FeK7ZzMv5hHqL06Hn6JIhn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;제품 정면 : 버즈4 프로 케이스의 정면 디자인과 전체적인 인상을 볼 수 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVn6LK/dJMcagLsVFG/wckvhg102Lw7NbZTiSoh5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVn6LK/dJMcagLsVFG/wckvhg102Lw7NbZTiSoh5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVn6LK/dJMcagLsVFG/wckvhg102Lw7NbZTiSoh5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVn6LK%2FdJMcagLsVFG%2Fwckvhg102Lw7NbZTiSoh5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;이어폰 자세히 보기 : 이어버드 본체의 형태와 디테일을 가까이서 확인할 수 있는 사진입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_grid&quot;&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdbJKY/dJMcagLsVFH/ODXSy0tVXAgT8O7zzwg4Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdbJKY/dJMcagLsVFH/ODXSy0tVXAgT8O7zzwg4Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdbJKY/dJMcagLsVFH/ODXSy0tVXAgT8O7zzwg4Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdbJKY%2FdJMcagLsVFH%2FODXSy0tVXAgT8O7zzwg4Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;충전 타입 사진 : USB-C 타입 포트를 확인할 수 있는 사진입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6zOsc/dJMcagSd3wJ/ZjzG7MMrRCjaUzIXuKCcLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6zOsc/dJMcagSd3wJ/ZjzG7MMrRCjaUzIXuKCcLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6zOsc/dJMcagSd3wJ/ZjzG7MMrRCjaUzIXuKCcLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6zOsc%2FdJMcagSd3wJ%2FZjzG7MMrRCjaUzIXuKCcLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;충전 타입 반대편 : 반대편 삼성 로고가 보이는 외관 컷입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 보면서 좋았던 부분은 과한 장식 없이 제품 자체의 디테일로 승부한다는 느낌이 있다는 점이었습니다. 설명 : USB-C 포트 같은 실사용 요소도 깔끔하게 정리되어 있고, 케이스 외관 역시 어느 방향에서 봐도 무난하게 잘 떨어지는 편입니다. 괜히 책상 위에 올려두고 한 번 더 보게 되는 타입이라고 하면 느낌이 좀 전달될 것 같습니다.&lt;/p&gt;
&lt;ul class=&quot;samsungbuds_keypoints&quot; 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;USB-C 타입 채택으로 충전 편의성 확보&lt;/li&gt;
&lt;li&gt;삼성 로고와 외관 디테일이 과하지 않으면서 깔끔함&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_sec3&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;케이스 구조와 충전 편의성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스를 열고 닫는 흐름, 이어버드를 꺼내고 다시 넣는 과정, 충전 상태를 확인하는 방식은 생각보다 자주 반복되는 동작입니다. 그래서 이런 부분이 불편하면 사소해 보여도 만족도에 꽤 영향을 줍니다. 갤럭시 버즈4 프로는 실제로 케이스를 다루는 과정이 비교적 직관적인 편이었습니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_photo_grid&quot;&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMeiTt/dJMcaiibC9b/hrTcwGPiG06Z7KeeYFFMv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMeiTt/dJMcaiibC9b/hrTcwGPiG06Z7KeeYFFMv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMeiTt/dJMcaiibC9b/hrTcwGPiG06Z7KeeYFFMv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMeiTt%2FdJMcaiibC9b%2FhrTcwGPiG06Z7KeeYFFMv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;본체에서 이어폰을 모두 꺼낸 뒤 사진 : 케이스 내부 구조를 확인할 수 있는 컷입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_photo_item&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nb7Ma/dJMcagLsVFI/nxGqWlAP7kPgg43f64jWb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nb7Ma/dJMcagLsVFI/nxGqWlAP7kPgg43f64jWb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nb7Ma/dJMcagLsVFI/nxGqWlAP7kPgg43f64jWb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNb7Ma%2FdJMcagLsVFI%2FnxGqWlAP7kPgg43f64jWb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;samsungbuds_caption&quot;&gt;충전 중인 버즈4 프로 : 이어버드가 케이스 안에서 충전되는 모습을 확인할 수 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명 : 이런 사진은 실제 리뷰에서 꽤 중요합니다. 왜냐하면 제품을 살 때 사람들은 예쁜 홍보 이미지보다 &amp;ldquo;진짜 손으로 쓰면 어떤 느낌인지&amp;rdquo;가 궁금하기 때문입니다. 케이스 내부 구조나 충전 상태를 보여주는 컷이 있으면 글의 신뢰감도 확실히 올라갑니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_quote&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품 사진을 찍다 보면 어느 순간 &amp;lsquo;내가 지금 리뷰를 쓰는 건지, 제품 사진작가가 된 건지&amp;rsquo; 헷갈릴 때가 있는데, 케이스 내부 컷은 그만큼 실제 사용 느낌을 잘 보여주는 사진입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_sec4&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;Hi-Fi 사운드 사용 후기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갤럭시 버즈4 프로를 사용하면서 가장 먼저 체크한 부분은 역시 음질이었습니다. 다양한 장르의 음악을 들어보니 전반적으로 보컬과 배경 사운드가 비교적 선명하게 분리되어 들렸고, 저음도 과하게 부풀기보다는 안정적으로 받쳐주는 인상이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 평소 자주 듣던 음악을 다시 틀어보면 작은 차이가 더 잘 느껴집니다. 익숙한 곡일수록 &amp;lsquo;어, 이 부분이 좀 더 또렷하네&amp;rsquo; 같은 순간이 잘 보이는데, 갤럭시 버즈4 프로는 그런 포인트가 은근히 있었습니다. 처음부터 과하게 화려한 소리라기보다는, 들을수록 밸런스가 괜찮다는 쪽에 가까웠습니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_split&quot;&gt;
&lt;div class=&quot;samsungbuds_card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실사용 체감&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출퇴근길이나 실내 집중 시간처럼 비교적 긴 시간 음악을 들을 때 전체 음색이 안정적으로 유지되어 피로감이 덜한 편이었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;한 줄 정리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명 : 하이파이 사운드를 너무 과장하지 않으면서도, 기존보다 더 정리된 느낌이라는 점은 충분히 체감할 수 있었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul class=&quot;samsungbuds_keypoints&quot; 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;갤럭시 버즈4 프로 음질 후기를 쓰기 좋은 분명한 포인트가 있었음&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_sec5&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;초광대역 통화와 Galaxy AI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무선이어폰은 이제 음악만 듣는 기기가 아니기 때문에, 통화 품질과 보조 기능의 완성도가 점점 더 중요해지고 있습니다. 갤럭시 버즈4 프로는 실제로 실내는 물론 외부 소음이 어느 정도 있는 환경에서도 비교적 안정적인 통화 경험을 보여주었습니다. 상대방 목소리도 답답하지 않았고, 제 목소리 전달 역시 무난하게 이어졌습니다.&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;그리고 이번에 꽤 흥미로웠던 부분은 Galaxy AI와 연결되는 흐름이었습니다. 이어버드가 단순한 오디오 액세서리를 넘어, 스마트폰과 함께 움직이는 인터페이스처럼 느껴지는 순간들이 있었습니다. 손이 자유롭지 않은 상황에서 빠르게 반응할 수 있다는 점은 실제로 써보면 생각보다 편리합니다.&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 기능은 눌러서 써보기 전보다 익숙해진 뒤가 더 편해지는 법인데, 이번에는 둘 다 실사용에서 꽤 인상이 좋았습니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_quote&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대방이 &amp;ldquo;밖이야?&amp;rdquo;보다 &amp;ldquo;목소리 괜찮네&amp;rdquo;라고 말해주면 그 통화 품질은 일단 합격이라고 생각합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_sec6&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;착용감과 이벤트 참여 관점 총평&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리 음질과 기능이 좋아도 착용감이 불편하면 결국 자주 쓰지 않게 됩니다. 그래서 개인적으로는 착용 안정감과 귀에 부담이 적은지를 꽤 중요하게 보는데, 갤럭시 버즈4 프로는 장시간 착용했을 때도 비교적 편안한 편이었습니다. 이동 중이나 가벼운 활동 중에도 크게 불안정하다는 느낌 없이 사용할 수 있었습니다.&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;이번 삼성전자 이벤트 참여 관점에서 봐도 포인트가 분명했습니다. Hi-Fi 사운드는 음악 감상 경험을, 초광대역 통화는 실용성을, Galaxy AI는 차별화 포인트를, 착용감은 실제 만족도를 설명하기에 좋았습니다. 즉, 억지로 포인트를 만들어내지 않아도 리뷰할 요소가 자연스럽게 나온다는 점이 장점이었습니다.&lt;/p&gt;
&lt;div class=&quot;samsungbuds_table_wrap&quot;&gt;
&lt;table class=&quot;samsungbuds_table&quot; 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;이벤트 포스팅 활용 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hi-Fi 사운드&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;실내&amp;middot;실외 모두에서 비교적 안정적인 통화 경험&lt;/td&gt;
&lt;td&gt;일상 통화, 업무 통화 후기와 연결하기 좋음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Galaxy AI&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;/div&gt;
&lt;div class=&quot;samsungbuds_note&quot;&gt;설명 : 이벤트 참여용 글에서는 기능을 나열하기보다, 언제 써봤고 어떤 상황에서 좋았는지를 함께 적어주면 훨씬 자연스럽고 신뢰감 있게 보입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;samsungbuds_outro&quot; class=&quot;samsungbuds_section&quot;&gt;
&lt;h2 class=&quot;samsungbuds_section_title&quot; data-ke-size=&quot;size26&quot;&gt;마무리! 갤럭시 버즈4 프로 추천 포인트 정리&lt;/h2&gt;
&lt;div class=&quot;samsungbuds_summary&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;총평&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갤럭시 버즈4 프로는 단순히 신제품이라는 이유만으로 눈길이 가는 무선이어폰이 아니라, 실제 사용 기준에서 음질, 통화 품질, Galaxy AI 활용성, 착용감까지 전체 밸런스가 잘 잡혀 있는 제품으로 느껴졌습니다.&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;ldquo;사진 찍기 좋은 제품&amp;rdquo;에서 끝나는 것이 아니라 실제로 자주 쓰게 되는 무선이어폰이라는 점에서 만족도가 높았습니다. 괜히 적을 포인트가 많은 제품이 아니었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;samsungbuds_tags&quot; style=&quot;margin-top: 16px;&quot;&gt;
&lt;h3 class=&quot;samsungbuds_tags_title&quot; data-ke-size=&quot;size23&quot;&gt;태그&lt;/h3&gt;
&lt;div class=&quot;samsungbuds_tag_list&quot;&gt;&lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 리뷰&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 후기&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 음질&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 통화 품질&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 착용감&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 Galaxy AI&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 이벤트&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;갤럭시 버즈4 프로 리뷰어 미션&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;버즈4 프로 하이파이 사운드&lt;/span&gt; &lt;span class=&quot;samsungbuds_tag&quot;&gt;버즈4 프로 초광대역 통화&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;div class=&quot;samsungbuds_footer&quot;&gt;이벤트 참여형 전문 리뷰 템플릿 &amp;middot; 티스토리 최적화 &amp;middot; SEO 키워드 자연 반영&lt;/div&gt;
&lt;/div&gt;</description>
      <category>IT/Product</category>
      <category>galaxyai</category>
      <category>GalaxyBuds4</category>
      <category>GalaxyBuds4Pro</category>
      <category>갤럭시버즈4ForU리뷰어</category>
      <category>갤럭시버즈4프로</category>
      <category>갤럭시버즈4프로리뷰</category>
      <category>삼성전자이벤트</category>
      <category>초광대역통화</category>
      <category>편안한착용감</category>
      <category>하이파이사운드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/575</guid>
      <comments>https://odinbox.tistory.com/575#entry575comment</comments>
      <pubDate>Mon, 9 Mar 2026 07:02:34 +0900</pubDate>
    </item>
    <item>
      <title>센과 치히로의 행방불명 오리지널 내한 공연 관람 후기</title>
      <link>https://odinbox.tistory.com/574</link>
      <description>&lt;div&gt;
&lt;style&gt;
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&amp;family=Noto+Serif+KR:wght@400;700;900&amp;display=swap');

    #magazine_post_wrapper {
        font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
        line-height: 1.8;
        color: #2c2c2c;
        max-width: 900px;
        margin: 0 auto;
        padding: 50px 20px;
        word-break: keep-all;
        background-color: #ffffff;
    }
    
    .magazine_header {
        text-align: center;
        margin-bottom: 60px;
    }
    
    .magazine_main_title {
        font-family: 'Noto Serif KR', 'Batang', serif;
        font-size: 36px;
        font-weight: 900;
        line-height: 1.45;
        color: #111;
        margin-bottom: 25px;
        letter-spacing: -0.5px;
    }
    
    .magazine_lead {
        font-size: 17px;
        color: #555;
        border-top: 2px solid #222;
        border-bottom: 1px solid #ddd;
        padding: 20px 10px;
        margin-bottom: 35px;
        text-align: justify;
        line-height: 1.7;
    }

    .magazine_sub_title {
        font-family: 'Noto Serif KR', 'Batang', serif;
        font-size: 24px;
        font-weight: 700;
        color: #1a1a1a;
        margin-top: 70px;
        margin-bottom: 25px;
        padding-bottom: 12px;
        border-bottom: 2px solid #222;
        letter-spacing: -0.5px;
    }

    .magazine_content_text {
        font-size: 16px;
        margin-bottom: 25px;
        text-align: justify;
        color: #333;
        font-weight: 400;
    }

    .magazine_info_box {
        margin: 50px 0;
        padding: 35px 30px;
        background-color: #f4f6f8;
        border-radius: 4px;
        border-top: 4px solid #2c3e50;
    }
    
    .magazine_info_title {
        font-family: 'Noto Serif KR', serif;
        font-size: 20px;
        font-weight: 700;
        color: #2c3e50;
        margin-bottom: 15px;
        display: flex;
        align-items: center;
    }
    
    .magazine_info_title::before {
        content: &quot;■&quot;;
        font-size: 14px;
        color: #e74c3c;
        margin-right: 10px;
    }

    .magazine_media_wrap {
        margin: 50px 0;
        text-align: center;
    }
    
    .magazine_media_wrap img, .magazine_media_wrap figure {
        max-width: 100%;
        height: auto;
        margin-bottom: 12px;
        border-radius: 2px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.06);
        transition: transform 0.3s ease;
    }
    
    .magazine_media_wrap img:hover {
        transform: scale(1.01);
    }
    
    .magazine_caption {
        font-size: 13px;
        color: #777;
        margin-top: 10px;
        text-align: center;
        font-weight: 300;
        letter-spacing: 0.5px;
    }

    .magazine_youtube_wrap {
        position: relative;
        width: 100%;
        padding-bottom: 56.25%;
        margin: 45px 0 15px 0;
        background-color: #000;
        border-radius: 4px;
        overflow: hidden;
    }
    
    .magazine_youtube_wrap iframe {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        border: none;
    }

    .magazine_quote_box {
        margin: 50px 0;
        padding: 35px;
        background-color: #fff;
        border: 1px solid #eaeaea;
        border-left: 5px solid #8b0000;
        font-family: 'Noto Serif KR', 'Batang', serif;
        box-shadow: 0 2px 8px rgba(0,0,0,0.02);
    }
    
    .magazine_quote_jp {
        font-size: 15px;
        color: #888;
        margin-bottom: 12px;
        font-style: italic;
    }
    
    .magazine_quote_kr {
        font-size: 21px;
        font-weight: 700;
        color: #111;
        margin-bottom: 20px;
        line-height: 1.5;
    }
    
    .magazine_quote_speaker {
        font-size: 14px;
        color: #8b0000;
        font-family: 'Noto Sans KR', sans-serif;
        text-align: right;
        font-weight: 700;
    }

    #magazine_tags_section {
        margin-top: 90px;
        padding-top: 35px;
        border-top: 1px solid #eee;
    }
    
    .magazine_tag_header {
        font-size: 13px;
        font-weight: 700;
        color: #aaa;
        margin-bottom: 12px;
        text-transform: uppercase;
        letter-spacing: 2px;
    }
    
    .magazine_tag_content {
        font-size: 14px;
        color: #34495e;
        margin-bottom: 25px;
        line-height: 1.7;
        word-break: keep-all;
    }
&lt;/style&gt;
&lt;/div&gt;
&lt;div id=&quot;magazine_post_wrapper&quot;&gt;
&lt;div class=&quot;magazine_header&quot;&gt;
&lt;h1 class=&quot;magazine_main_title&quot;&gt;지브리의 감동을 무대에서 만나다&lt;br /&gt;연극 '센과 치히로의 행방불명' 오리지널 투어 관람기&lt;/h1&gt;
&lt;div class=&quot;magazine_lead&quot;&gt;세계적인 명작 애니메이션이 토니상 수상 연출가 존 케어드(John Caird)의 손을 거쳐 무대 위 아날로그 예술로 재탄생했다. 울산에서 서울 예술의전당까지, 스크린 속 신들의 세계를 실물로 마주한 2026년 2월의 기록을 심층적으로 분석한다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmvisF/dJMcagLoRWw/NHoQf4EhqPt0O4Df0FkoTk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmvisF/dJMcagLoRWw/NHoQf4EhqPt0O4Df0FkoTk/img.gif&quot; data-alt=&quot;뮤지컬 공식 포스터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmvisF/dJMcagLoRWw/NHoQf4EhqPt0O4Df0FkoTk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dmvisF/dJMcagLoRWw/NHoQf4EhqPt0O4Df0FkoTk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;1000&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뮤지컬 공식 포스터&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;div class=&quot;magazine_caption&quot;&gt;센과 치히로의 행방불명 오리지널 투어 공식 포스터&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;썸네일.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rbepn/dJMcagLoNoH/NK7YouVxywxtZizL9BNmx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rbepn/dJMcagLoNoH/NK7YouVxywxtZizL9BNmx1/img.png&quot; data-alt=&quot;썸네일 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rbepn/dJMcagLoNoH/NK7YouVxywxtZizL9BNmx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frbepn%2FdJMcagLoNoH%2FNK7YouVxywxtZizL9BNmx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;썸네일 이미지&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;썸네일.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;썸네일 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 class=&quot;magazine_sub_title&quot; data-ke-size=&quot;size26&quot;&gt;새벽 KTX를 타고 마주한 지브리의 세계&lt;/h2&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;지브리 스튜디오의 애니메이션 중에서도 전 세계적으로 가장 높은 평가를 받는 명작, '센과 치히로의 행방불명'이 오리지널 투어로 내한한다는 소식을 듣고 울산에서 서울까지 긴 여정을 계획했다. 2026년 2월 28일 토요일 오후 2시 공연 관람을 위해 아침 일찍부터 서둘렀던 그날의 동선과 현장 분위기를 상세히 서술한다.&lt;/p&gt;
&lt;div class=&quot;magazine_youtube_wrap&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/ajabjhn2k7c?si=B8lNhZRyTBd_hREU&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class=&quot;magazine_caption&quot;&gt;▲ 센과 치히로의 행방불명 오리지널 투어 SPOT 영상&lt;/div&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;아침 6시 30분 울산역에서 출발하는 KTX에 탑승하여 서울역에 도착하니 오전 9시가 조금 넘은 시각이었다. 지체 없이 택시를 이용하여 예술의전당으로 이동했다. 공연 시간까지 충분한 여유가 있었으므로, 전당 내부 구조를 살펴보고 카페에서 휴식을 취하며 관람을 준비했다. 오페라극장 홀 입장은 공연 시작 1시간 30분 전부터 허용되며, 12시 30분이 되자마자 1층 예매처에서 첫 번째로 티켓을 수령할 수 있었다.&lt;/p&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KnlDl/dJMcad18Bwb/kMbMtW4ISeL1pwih8wkKB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KnlDl/dJMcad18Bwb/kMbMtW4ISeL1pwih8wkKB1/img.png&quot; data-alt=&quot;출발 전 찍은 울산역 고래 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KnlDl/dJMcad18Bwb/kMbMtW4ISeL1pwih8wkKB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKnlDl%2FdJMcad18Bwb%2FkMbMtW4ISeL1pwih8wkKB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;출발 전 찍은 울산역 고래 조형물&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출발 전 찍은 울산역 고래 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/srKON/dJMcaf6LDgE/aKK2Dp1KmteS1XKt7llfDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/srKON/dJMcaf6LDgE/aKK2Dp1KmteS1XKt7llfDk/img.png&quot; data-alt=&quot;출발전 찍은 울산역 전경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/srKON/dJMcaf6LDgE/aKK2Dp1KmteS1XKt7llfDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsrKON%2FdJMcaf6LDgE%2FaKK2Dp1KmteS1XKt7llfDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;출발전 찍은 울산역 전경&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출발전 찍은 울산역 전경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzuhS/dJMcad18Bv6/35tDIJWkHB3HUhBk1H5RW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzuhS/dJMcad18Bv6/35tDIJWkHB3HUhBk1H5RW0/img.png&quot; data-alt=&quot;에술의전당 입구&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzuhS/dJMcad18Bv6/35tDIJWkHB3HUhBk1H5RW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzuhS%2FdJMcad18Bv6%2F35tDIJWkHB3HUhBk1H5RW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;에술의전당 입구&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;에술의전당 입구&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgpdiu/dJMcad18Bv9/CQoduNDLJm4udT7nugXJD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgpdiu/dJMcad18Bv9/CQoduNDLJm4udT7nugXJD0/img.png&quot; data-alt=&quot;예술의극장 지하 1층 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgpdiu/dJMcad18Bv9/CQoduNDLJm4udT7nugXJD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbgpdiu%2FdJMcad18Bv9%2FCQoduNDLJm4udT7nugXJD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;예술의극장 지하 1층 조형물&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예술의극장 지하 1층 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bElhPp/dJMb996y4md/9PQfSrv7hvh9WItiQXfpAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bElhPp/dJMb996y4md/9PQfSrv7hvh9WItiQXfpAK/img.png&quot; data-alt=&quot;예술의극장 지하1층 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bElhPp/dJMb996y4md/9PQfSrv7hvh9WItiQXfpAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbElhPp%2FdJMb996y4md%2F9PQfSrv7hvh9WItiQXfpAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;예술의극장 지하1층 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예술의극장 지하1층 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;magazine_quote_box&quot;&gt;
&lt;div class=&quot;magazine_quote_jp&quot;&gt;名前を奪われると、帰り道が分からなくなるんだよ。&lt;/div&gt;
&lt;div class=&quot;magazine_quote_kr&quot;&gt;&quot;이름을 빼앗기면 돌아가는 길을 알 수 없게 돼.&quot;&lt;/div&gt;
&lt;div class=&quot;magazine_quote_speaker&quot;&gt;- 하쿠 (ハク)&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class=&quot;magazine_sub_title&quot; data-ke-size=&quot;size26&quot;&gt;공연장 인프라, 굿즈 수령과 포토존 활용&lt;/h2&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;이번 내한 공연의 MD(굿즈) 부스는 예매 티켓 소지자에 한해 이용이 제한되었다. 이미 품절된 품목이 다수 존재했으나, 티켓을 조기 수령한 덕분에 사전에 계획했던 프로그램북, OST CD, 기념 뱃지를 원활하게 확보할 수 있었다.&lt;/p&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;1층에는 하쿠의 특성을 시각화한 메인 포토존이 설치되어 있다. 조명을 활용한 연출이 돋보이며 시각적 완성도가 높다. 관람객의 분산을 위해 2층과 3층에도 각각 독립된 포토존이 운영되었다.&lt;/p&gt;
&lt;iframe mapdata=&quot;addr=%EC%84%9C%EC%9A%B8%20%EC%84%9C%EC%B4%88%EA%B5%AC%20%EC%84%9C%EC%B4%88%EB%8F%99%20700&amp;amp;addtype=1&amp;amp;confirmid=17344023&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A503040%2C%22mapCenterY%22%3A1105553%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A503041%2C%22y%22%3A1105558%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EC%98%88%EC%88%A0%EC%9D%98%EC%A0%84%EB%8B%B9%22%2C%22confirmid%22%3A17344023%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=503040&amp;amp;mapY=1105553&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1165053000&amp;amp;tel=1668-1352&amp;amp;title=%EC%98%88%EC%88%A0%EC%9D%98%EC%A0%84%EB%8B%B9&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1772384805392&quot; id=&quot;maps_1772384805392&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EC%84%9C%EC%9A%B8%20%EC%84%9C%EC%B4%88%EA%B5%AC%20%EC%84%9C%EC%B4%88%EB%8F%99%20700&amp;amp;addtype=1&amp;amp;confirmid=17344023&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A503040%2C%22mapCenterY%22%3A1105553%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A503041%2C%22y%22%3A1105558%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EC%98%88%EC%88%A0%EC%9D%98%EC%A0%84%EB%8B%B9%22%2C%22confirmid%22%3A17344023%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=503040&amp;amp;mapY=1105553&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1165053000&amp;amp;tel=1668-1352&amp;amp;title=%EC%98%88%EC%88%A0%EC%9D%98%EC%A0%84%EB%8B%B9&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=503040%2C1105553&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A503041%2C1105558&quot;&gt;&lt;/iframe&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctdxm3/dJMcaa5tbBf/XXupOYnGgzJ2K9o33YHkdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctdxm3/dJMcaa5tbBf/XXupOYnGgzJ2K9o33YHkdK/img.png&quot; data-alt=&quot;1층 오페라극장 들어가기전 입구 (1시간 30분전부터입장가능)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctdxm3/dJMcaa5tbBf/XXupOYnGgzJ2K9o33YHkdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fctdxm3%2FdJMcaa5tbBf%2FXXupOYnGgzJ2K9o33YHkdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 오페라극장 들어가기전 입구 (1시간 30분전부터입장가능)&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 오페라극장 들어가기전 입구 (1시간 30분전부터입장가능)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JUSHS/dJMb996y4mc/RqCGBaF7weiCoMx4tBr58K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JUSHS/dJMb996y4mc/RqCGBaF7weiCoMx4tBr58K/img.png&quot; data-alt=&quot;1층 입구 모습(오페라극장)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JUSHS/dJMb996y4mc/RqCGBaF7weiCoMx4tBr58K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJUSHS%2FdJMb996y4mc%2FRqCGBaF7weiCoMx4tBr58K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 입구 모습(오페라극장)&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 입구 모습(오페라극장)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oxC8x/dJMcad18BvR/wJn7B2mdh5biHyI5L5Sbr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oxC8x/dJMcad18BvR/wJn7B2mdh5biHyI5L5Sbr1/img.png&quot; data-alt=&quot;오페라극장 바로 앞모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oxC8x/dJMcad18BvR/wJn7B2mdh5biHyI5L5Sbr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoxC8x%2FdJMcad18BvR%2FwJn7B2mdh5biHyI5L5Sbr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;오페라극장 바로 앞모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오페라극장 바로 앞모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AJhH9/dJMcad18BvX/wOBHiWcpqWp8fQiq2ROko1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AJhH9/dJMcad18BvX/wOBHiWcpqWp8fQiq2ROko1/img.png&quot; data-alt=&quot;오페라극장 건물외부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AJhH9/dJMcad18BvX/wOBHiWcpqWp8fQiq2ROko1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAJhH9%2FdJMcad18BvX%2FwOBHiWcpqWp8fQiq2ROko1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;오페라극장 건물외부&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오페라극장 건물외부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf7uWI/dJMcaca9f4s/lVMoQQTd4XyAeNhEAREnyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf7uWI/dJMcaca9f4s/lVMoQQTd4XyAeNhEAREnyK/img.png&quot; data-alt=&quot;1층 옆에 걸려있는 포스터들 모음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf7uWI/dJMcaca9f4s/lVMoQQTd4XyAeNhEAREnyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf7uWI%2FdJMcaca9f4s%2FlVMoQQTd4XyAeNhEAREnyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 옆에 걸려있는 포스터들 모음&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 옆에 걸려있는 포스터들 모음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T6xXb/dJMb996y4mb/u8GG9tEHptVbvTsKzqoNiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T6xXb/dJMb996y4mb/u8GG9tEHptVbvTsKzqoNiK/img.png&quot; data-alt=&quot;1층 포토존 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T6xXb/dJMb996y4mb/u8GG9tEHptVbvTsKzqoNiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT6xXb%2FdJMb996y4mb%2Fu8GG9tEHptVbvTsKzqoNiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 포토존 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 포토존 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UXT5L/dJMcaa5tbBh/KaNLeAPeMvcR2fXC97hYT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UXT5L/dJMcaa5tbBh/KaNLeAPeMvcR2fXC97hYT1/img.png&quot; data-alt=&quot;시작 전인 1층 모습(불꺼져있음)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UXT5L/dJMcaa5tbBh/KaNLeAPeMvcR2fXC97hYT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUXT5L%2FdJMcaa5tbBh%2FKaNLeAPeMvcR2fXC97hYT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;시작 전인 1층 모습(불꺼져있음)&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시작 전인 1층 모습(불꺼져있음)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L440A/dJMcad18Bv8/FqMWodsfRT63jSBB2JzVrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L440A/dJMcad18Bv8/FqMWodsfRT63jSBB2JzVrk/img.png&quot; data-alt=&quot;영화포스터대형현수막&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L440A/dJMcad18Bv8/FqMWodsfRT63jSBB2JzVrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL440A%2FdJMcad18Bv8%2FFqMWodsfRT63jSBB2JzVrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;영화포스터대형현수막&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;영화포스터대형현수막&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yLSKU/dJMcaca9f4o/VnKJmN46ISM0gkS6KQZ3l0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yLSKU/dJMcaca9f4o/VnKJmN46ISM0gkS6KQZ3l0/img.png&quot; data-alt=&quot;공연장 입장전찍은모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yLSKU/dJMcaca9f4o/VnKJmN46ISM0gkS6KQZ3l0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyLSKU%2FdJMcaca9f4o%2FVnKJmN46ISM0gkS6KQZ3l0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;공연장 입장전찍은모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공연장 입장전찍은모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AKOrn/dJMcaadleHd/Su7H6tAkNK46SqfiXknWlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AKOrn/dJMcaadleHd/Su7H6tAkNK46SqfiXknWlk/img.png&quot; data-alt=&quot;1층 포토존 모습 위에서 바라봄&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AKOrn/dJMcaadleHd/Su7H6tAkNK46SqfiXknWlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAKOrn%2FdJMcaadleHd%2FSu7H6tAkNK46SqfiXknWlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 포토존 모습 위에서 바라봄&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 포토존 모습 위에서 바라봄&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPH2Cf/dJMcaca9f4t/Mk0RyUhwDcaQrkNVMUYfv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPH2Cf/dJMcaca9f4t/Mk0RyUhwDcaQrkNVMUYfv0/img.png&quot; data-alt=&quot;1층 티켓수령장소 바로 앞&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPH2Cf/dJMcaca9f4t/Mk0RyUhwDcaQrkNVMUYfv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPH2Cf%2FdJMcaca9f4t%2FMk0RyUhwDcaQrkNVMUYfv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 티켓수령장소 바로 앞&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 티켓수령장소 바로 앞&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF1bFY/dJMcad18BvE/pC2ONjvl6l2PjmLKqdEL01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF1bFY/dJMcad18BvE/pC2ONjvl6l2PjmLKqdEL01/img.png&quot; data-alt=&quot;기념품 가오나시 뱃지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF1bFY/dJMcad18BvE/pC2ONjvl6l2PjmLKqdEL01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF1bFY%2FdJMcad18BvE%2FpC2ONjvl6l2PjmLKqdEL01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;기념품 가오나시 뱃지&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기념품 가오나시 뱃지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfJi1k/dJMb996y4xc/4h8WLFK7CMMSn4qTciy9Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfJi1k/dJMb996y4xc/4h8WLFK7CMMSn4qTciy9Kk/img.png&quot; data-alt=&quot;입장권&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfJi1k/dJMb996y4xc/4h8WLFK7CMMSn4qTciy9Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfJi1k%2FdJMb996y4xc%2F4h8WLFK7CMMSn4qTciy9Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;입장권&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;입장권&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpmytM/dJMcad18BvM/6vq5yltedSA5aFlOBnpgx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpmytM/dJMcad18BvM/6vq5yltedSA5aFlOBnpgx1/img.png&quot; data-alt=&quot;1층 기둥 포스 터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpmytM/dJMcad18BvM/6vq5yltedSA5aFlOBnpgx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpmytM%2FdJMcad18BvM%2F6vq5yltedSA5aFlOBnpgx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 기둥 포스 터&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 기둥 포스 터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VRtE6/dJMcad18BvO/4w1bU3BjVSHXklDJZVyBCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VRtE6/dJMcad18BvO/4w1bU3BjVSHXklDJZVyBCk/img.png&quot; data-alt=&quot;1층 디지털 포스터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VRtE6/dJMcad18BvO/4w1bU3BjVSHXklDJZVyBCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVRtE6%2FdJMcad18BvO%2F4w1bU3BjVSHXklDJZVyBCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 디지털 포스터&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 디지털 포스터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmtgjt/dJMcaca9f4l/9TwY2xLfEzooIeUQg2TJIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmtgjt/dJMcaca9f4l/9TwY2xLfEzooIeUQg2TJIK/img.png&quot; data-alt=&quot;1층 포스트 기둥&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmtgjt/dJMcaca9f4l/9TwY2xLfEzooIeUQg2TJIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcmtgjt%2FdJMcaca9f4l%2F9TwY2xLfEzooIeUQg2TJIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 포스트 기둥&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 포스트 기둥&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC3wSF/dJMcaadleHa/Wi2cF10UdtkJdqxlg9LEo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC3wSF/dJMcaadleHa/Wi2cF10UdtkJdqxlg9LEo1/img.png&quot; data-alt=&quot;1층 포토존 뒤에 가오나시 그림&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC3wSF/dJMcaadleHa/Wi2cF10UdtkJdqxlg9LEo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC3wSF%2FdJMcaadleHa%2FWi2cF10UdtkJdqxlg9LEo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 포토존 뒤에 가오나시 그림&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 포토존 뒤에 가오나시 그림&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;3층에 마련된 '신들의 온천장'은 사전 예약 굿즈의 수령처인 동시에 전시 기능을 겸하고 있다. 더불어 소원나무 트리와 무료 엽서 배포 공간이 마련되어 있으며, 치히로가 바닷가에서 신발을 들고 있는 명장면을 재현한 포토존은 관람객들에게 높은 호응을 얻었다.&lt;/p&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9ZwVR/dJMcaca9f4n/khe4GCxKkpFICgh00FI0K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9ZwVR/dJMcaca9f4n/khe4GCxKkpFICgh00FI0K1/img.png&quot; data-alt=&quot;신들의온천장 근처에 있는 포토존 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9ZwVR/dJMcaca9f4n/khe4GCxKkpFICgh00FI0K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9ZwVR%2FdJMcaca9f4n%2Fkhe4GCxKkpFICgh00FI0K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;신들의온천장 근처에 있는 포토존 1&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;신들의온천장 근처에 있는 포토존 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJBaCy/dJMcad18BvU/2qVM5JANBFvdFQ9fzCzT31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJBaCy/dJMcad18BvU/2qVM5JANBFvdFQ9fzCzT31/img.png&quot; data-alt=&quot;신들의온천장 근처에 있는 포토존2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJBaCy/dJMcad18BvU/2qVM5JANBFvdFQ9fzCzT31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJBaCy%2FdJMcad18BvU%2F2qVM5JANBFvdFQ9fzCzT31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;신들의온천장 근처에 있는 포토존2&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;신들의온천장 근처에 있는 포토존2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOwkDn/dJMcaca9f4p/o0KBaLMjGQ5RzwdkHJ0ae0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOwkDn/dJMcaca9f4p/o0KBaLMjGQ5RzwdkHJ0ae0/img.png&quot; data-alt=&quot;신들의 온천장 근처에 있는 포토존 두개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOwkDn/dJMcaca9f4p/o0KBaLMjGQ5RzwdkHJ0ae0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOwkDn%2FdJMcaca9f4p%2Fo0KBaLMjGQ5RzwdkHJ0ae0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;신들의 온천장 근처에 있는 포토존 두개&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;신들의 온천장 근처에 있는 포토존 두개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 class=&quot;magazine_sub_title&quot; data-ke-size=&quot;size26&quot;&gt;무대 연출 및 좌석 시야 분석&lt;/h2&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;공연은 1부 85분, 인터미션 20분, 2부 75분 등 총 3시간에 걸쳐 진행되었다. 예매한 좌석은 1층 C열 21번 3번이었다. 예매 전 해당 구역의 시야 확보에 대한 우려가 있었으나, 실제 착석 결과 무대 전체의 미장센을 조망하는 데 큰 무리가 없었다.&lt;/p&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lHS8e/dJMcaadleHb/YEzvR40lgOxxWKCaZIvNr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lHS8e/dJMcaadleHb/YEzvR40lgOxxWKCaZIvNr0/img.png&quot; data-alt=&quot;1층 좌석배치도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lHS8e/dJMcaadleHb/YEzvR40lgOxxWKCaZIvNr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlHS8e%2FdJMcaadleHb%2FYEzvR40lgOxxWKCaZIvNr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;1층 좌석배치도&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1층 좌석배치도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k4Lq6/dJMcaf6LDgF/8lbohwbVPqEeELh0F5TFIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k4Lq6/dJMcaf6LDgF/8lbohwbVPqEeELh0F5TFIk/img.png&quot; data-alt=&quot;공연장 안 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k4Lq6/dJMcaf6LDgF/8lbohwbVPqEeELh0F5TFIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk4Lq6%2FdJMcaf6LDgF%2F8lbohwbVPqEeELh0F5TFIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;공연장 안 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공연장 안 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqgLoU/dJMcaca9f4k/XmlftX4aUDdSYDkvQQeaWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqgLoU/dJMcaca9f4k/XmlftX4aUDdSYDkvQQeaWK/img.png&quot; data-alt=&quot;공연장 안 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqgLoU/dJMcaca9f4k/XmlftX4aUDdSYDkvQQeaWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqgLoU%2FdJMcaca9f4k%2FXmlftX4aUDdSYDkvQQeaWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;공연장 안 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공연장 안 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;다만, 배우들의 세밀한 표정 연기를 관찰하기 위해서는 오페라글라스 지참을 권장한다. 본 공연은 일본어 원어로 진행되며 한국어 자막이 제공된다. 따라서 자막기의 위치와 좌석의 시야각을 종합적으로 고려하여 예매하는 것이 원활한 관람의 핵심이다. (공연 중 휴대전화 전원 차단 및 커튼콜을 포함한 전 구간 촬영 금지 규정이 엄격히 적용된다.)&lt;/p&gt;
&lt;div class=&quot;magazine_quote_box&quot;&gt;
&lt;div class=&quot;magazine_quote_jp&quot;&gt;ここで働かせてください！&lt;/div&gt;
&lt;div class=&quot;magazine_quote_kr&quot;&gt;&quot;여기서 일하게 해주세요!&quot;&lt;/div&gt;
&lt;div class=&quot;magazine_quote_speaker&quot;&gt;- 치히로 (千尋)&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class=&quot;magazine_sub_title&quot; data-ke-size=&quot;size26&quot;&gt;아날로그 예술의 극치, 무대와 배우들의 열연&lt;/h2&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;이번 연극이 전 세계적인 호평을 받는 이유는 원작의 판타지적 요소를 CG가 아닌 철저한 '아날로그 무대 장치'와 '퍼핏(인형)' 기술로 구현했다는 점에 있다. 영국의 저명한 퍼핏 디자이너 토비 올리에(Toby Oli&amp;eacute;)의 기술력이 더해져, 스크린 속 정령들과 요괴들이 인간의 신체 움직임과 결합하여 물리적인 무대 위에서 생동감 있게 살아 움직인다.&lt;/p&gt;
&lt;div class=&quot;magazine_youtube_wrap&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/6WkHf8jlkVQ?si=OLDNwglzy6TgAWQd&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class=&quot;magazine_caption&quot;&gt;▲ 센과 치히로의 행방불명 오리지널 투어 무대 셋업 타임랩스&lt;/div&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;관람 회차의 캐스팅 역시 원작과의 높은 싱크로율을 입증했다. 치히로 역의 카와에이 리나는 두려움에 떨던 소녀가 주체적인 인물로 성장해 가는 궤적을 에너제틱하게 소화해 냈다. 하쿠 역의 아쿠츠 니치카는 절도 있는 동선 처리로 캐릭터 특유의 신비로움을 유지했다.&lt;/p&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;특히 유바바와 제니바 1인 2역을 맡은 타카하시 히토미는 베테랑 배우의 관록을 증명하듯, 탐욕과 포용력이라는 양극단의 감정을 완벽하게 분리하여 연기했다. 사와무라 료(가오나시 역)의 섬세한 안무적 표현, 만타니 노리히데(가마 할아범 역)의 안정적인 조력자 연기 또한 무대의 입체감을 더하는 데 크게 기여했다.&lt;/p&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oi3sV/dJMcad18BHP/wkozYmFFc8lh52nsO5Tdnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oi3sV/dJMcad18BHP/wkozYmFFc8lh52nsO5Tdnk/img.png&quot; data-alt=&quot;예술의 전당 앞 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oi3sV/dJMcad18BHP/wkozYmFFc8lh52nsO5Tdnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foi3sV%2FdJMcad18BHP%2FwkozYmFFc8lh52nsO5Tdnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;예술의 전당 앞 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예술의 전당 앞 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oi3sV/dJMcad18BHP/wkozYmFFc8lh52nsO5Tdnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oi3sV/dJMcad18BHP/wkozYmFFc8lh52nsO5Tdnk/img.png&quot; data-alt=&quot;예술의 전당 앞 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oi3sV/dJMcad18BHP/wkozYmFFc8lh52nsO5Tdnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foi3sV%2FdJMcad18BHP%2FwkozYmFFc8lh52nsO5Tdnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;예술의 전당 앞 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예술의 전당 앞 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E7mdm/dJMcad18BvW/lm42ZEUuT2AEEgoaR9TbKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E7mdm/dJMcad18BvW/lm42ZEUuT2AEEgoaR9TbKk/img.png&quot; data-alt=&quot;예술의 전당 가로등에 걸린 뮤지컬포스터 홍보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E7mdm/dJMcad18BvW/lm42ZEUuT2AEEgoaR9TbKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE7mdm%2FdJMcad18BvW%2Flm42ZEUuT2AEEgoaR9TbKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;예술의 전당 가로등에 걸린 뮤지컬포스터 홍보&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예술의 전당 가로등에 걸린 뮤지컬포스터 홍보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YdmI4/dJMcad18Bwe/Y8iEESRgf3k2MlaTBuq7Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YdmI4/dJMcad18Bwe/Y8iEESRgf3k2MlaTBuq7Kk/img.png&quot; data-alt=&quot;예술의전당 벽에 걸린 뮤지컬 홍보 포스터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YdmI4/dJMcad18Bwe/Y8iEESRgf3k2MlaTBuq7Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYdmI4%2FdJMcad18Bwe%2FY8iEESRgf3k2MlaTBuq7Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;예술의전당 벽에 걸린 뮤지컬 홍보 포스터&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예술의전당 벽에 걸린 뮤지컬 홍보 포스터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BzRGl/dJMcahXPd99/jIoUempfQRVHi1eQv6E1Rk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BzRGl/dJMcahXPd99/jIoUempfQRVHi1eQv6E1Rk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BzRGl/dJMcahXPd99/jIoUempfQRVHi1eQv6E1Rk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBzRGl%2FdJMcahXPd99%2FjIoUempfQRVHi1eQv6E1Rk%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;700&quot; height=&quot;301&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;magazine_caption&quot;&gt;Photo by Johan Persson, 공연 中&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;magazine_quote_box&quot;&gt;
&lt;div class=&quot;magazine_quote_jp&quot;&gt;一度あったことは忘れないものさ。思い出せないだけで。&lt;/div&gt;
&lt;div class=&quot;magazine_quote_kr&quot;&gt;&quot;한 번 만난 인연은 잊히는 것이 아니라, 잊고 있을 뿐이란다.&quot;&lt;/div&gt;
&lt;div class=&quot;magazine_quote_speaker&quot;&gt;- 제니바 (銭婆)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;magazine_info_box&quot;&gt;
&lt;div class=&quot;magazine_info_title&quot;&gt;FACT CHECK : 뮤지컬인가, 연극인가?&lt;/div&gt;
&lt;p class=&quot;magazine_content_text&quot; style=&quot;margin-bottom: 10px; font-size: 15px;&quot; data-ke-size=&quot;size16&quot;&gt;압도적인 무대 스케일과 라이브 오케스트라의 존재로 인해 관람객들조차 이 작품을 '뮤지컬'로 오해하는 경우가 빈번하다. 인터파크 등 국내 주요 예매처 역시 마케팅 효과와 대극장 공연 시스템 분류의 편의를 위해 '뮤지컬' 카테고리에서 티켓을 판매하고 있다. &lt;b&gt;하지만 제작사가 명시한 이 작품의 공식 장르는 '연극(Play)'이다.&lt;/b&gt;&lt;/p&gt;
&lt;p class=&quot;magazine_content_text&quot; style=&quot;margin-bottom: 0; font-size: 15px;&quot; data-ke-size=&quot;size16&quot;&gt;뮤지컬은 극의 서사와 인물의 감정을 배우의 '가창(넘버)'을 통해 전개하는 것이 핵심이다. 반면, 본 공연은 철저하게 배우들의 대사와 신체 연기, 퍼핏 조종으로 서사를 이끌어간다. 11인조 오케스트라가 연주하는 히사이시 조의 명곡은 가창을 위한 반주가 아닌, 극의 분위기를 극대화하는 오리지널 사운드트랙(BGM)의 역할을 수행한다. 즉, 예매처의 분류와 대중적 인식은 '뮤지컬'일지라도, 작품의 본질적인 예술 형태는 음악이 가미된 &lt;b&gt;'대극장 연극'&lt;/b&gt;으로 이해하는 것이 정확하다.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 class=&quot;magazine_sub_title&quot; data-ke-size=&quot;size26&quot;&gt;커튼콜의 여운과 복귀 여정&lt;/h2&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;공연의 피날레를 장식한 커튼콜은 본 관람의 하이라이트라 할 수 있다. 무대 아래 가려져 있던 11인조 라이브 오케스트라 피트가 공개되고, 히사이시 조의 대표 명곡인 '또다시(Reprise)'가 웅장한 라이브 연주로 울려 퍼졌다. 19만 원이라는 티켓 가격은 결코 적은 금액이 아니나, 무대 메커니즘의 완성도와 오케스트라 라이브가 주는 공간감을 고려할 때 그 가치는 충분히 입증되었다.&lt;/p&gt;
&lt;div class=&quot;magazine_youtube_wrap&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/brHencVS5y4?si=2r3f_2XX6pj9mZi3&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class=&quot;magazine_caption&quot;&gt;▲ 센과 치히로의 행방불명 OST (또다시 Reprise)&lt;/div&gt;
&lt;p class=&quot;magazine_content_text&quot; data-ke-size=&quot;size16&quot;&gt;오후 5시경 예술의전당을 나서 서울역으로 이동했다. 기차 탑승 전 인근 식당에서 매운 낙지비빔국수로 저녁 식사를 해결하며 공연의 여운을 정리했다. 밤 8시 58분에 서울역을 출발한 KTX는 11시 23분 울산역에 도착했다. 주차장에 대기해 둔 차량을 이용하여 자택으로 복귀함으로써 당일치기 문화 기행이 마무리되었다. 물리적인 피로는 수반되었으나, 무대 위에서 완벽하게 재현된 지브리의 세계는 오랫동안 잊지 못할 예술적 경험으로 남을 것이다.&lt;/p&gt;
&lt;div class=&quot;magazine_media_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SkQyI/dJMcaca9f4j/MZtScaTNwlEtXAPQdGUoD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SkQyI/dJMcaca9f4j/MZtScaTNwlEtXAPQdGUoD1/img.png&quot; data-alt=&quot;신세계본점 대형 입체디스플레이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SkQyI/dJMcaca9f4j/MZtScaTNwlEtXAPQdGUoD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSkQyI%2FdJMcaca9f4j%2FMZtScaTNwlEtXAPQdGUoD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;신세계본점 대형 입체디스플레이&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;신세계본점 대형 입체디스플레이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfsF3B/dJMcabi1SDH/85VfNOWSViCVHM87X3ayCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfsF3B/dJMcabi1SDH/85VfNOWSViCVHM87X3ayCk/img.png&quot; data-alt=&quot;신세계본점 대형디스플레이 사진 찍으려는 사람들 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfsF3B/dJMcabi1SDH/85VfNOWSViCVHM87X3ayCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfsF3B%2FdJMcabi1SDH%2F85VfNOWSViCVHM87X3ayCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;신세계본점 대형디스플레이 사진 찍으려는 사람들 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;신세계본점 대형디스플레이 사진 찍으려는 사람들 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqKAR5/dJMcaadleG9/hFcRvrxJl3R1KjYWoRd8E1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqKAR5/dJMcaadleG9/hFcRvrxJl3R1KjYWoRd8E1/img.png&quot; data-alt=&quot;서울역 앞에 있는 건물 (드라마 미생에 나옴) 야경1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqKAR5/dJMcaadleG9/hFcRvrxJl3R1KjYWoRd8E1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqKAR5%2FdJMcaadleG9%2FhFcRvrxJl3R1KjYWoRd8E1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;서울역 앞에 있는 건물 (드라마 미생에 나옴) 야경1&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서울역 앞에 있는 건물 (드라마 미생에 나옴) 야경1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzybx/dJMcaadleG8/GNelmyK8IwYscXsMmelMjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzybx/dJMcaadleG8/GNelmyK8IwYscXsMmelMjk/img.png&quot; data-alt=&quot;서울역 앞에 있는 건물(드라마 미생에 나왔던 곳)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzybx/dJMcaadleG8/GNelmyK8IwYscXsMmelMjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkzybx%2FdJMcaadleG8%2FGNelmyK8IwYscXsMmelMjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;서울역 앞에 있는 건물(드라마 미생에 나왔던 곳)&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서울역 앞에 있는 건물(드라마 미생에 나왔던 곳)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxrODK/dJMcahDu70s/vEAeJr8u6nkTBglksDkcI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxrODK/dJMcahDu70s/vEAeJr8u6nkTBglksDkcI0/img.png&quot; data-alt=&quot;울산으로 출발하는 KTX 타기 전 서울역 플랫폼&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxrODK/dJMcahDu70s/vEAeJr8u6nkTBglksDkcI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxrODK%2FdJMcahDu70s%2FvEAeJr8u6nkTBglksDkcI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;울산으로 출발하는 KTX 타기 전 서울역 플랫폼&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;울산으로 출발하는 KTX 타기 전 서울역 플랫폼&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X5mFz/dJMcad18BHN/xJDR2lxVcQf6S4pK0IpAAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X5mFz/dJMcad18BHN/xJDR2lxVcQf6S4pK0IpAAK/img.png&quot; data-alt=&quot;서울역에서 울산출발 전 KTX찍은 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X5mFz/dJMcad18BHN/xJDR2lxVcQf6S4pK0IpAAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX5mFz%2FdJMcad18BHN%2FxJDR2lxVcQf6S4pK0IpAAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;서울역에서 울산출발 전 KTX찍은 모습&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서울역에서 울산출발 전 KTX찍은 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddnVQS/dJMcahDu70q/DcVeRoH4eln9bQlk05dlE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddnVQS/dJMcahDu70q/DcVeRoH4eln9bQlk05dlE1/img.png&quot; data-alt=&quot;울산 도착하고 집가다가 찍은 소나타 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddnVQS/dJMcahDu70q/DcVeRoH4eln9bQlk05dlE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddnVQS%2FdJMcahDu70q%2FDcVeRoH4eln9bQlk05dlE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;울산 도착하고 집가다가 찍은 소나타 모습&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;울산 도착하고 집가다가 찍은 소나타 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div id=&quot;magazine_tags_section&quot;&gt;
&lt;div class=&quot;magazine_tag_header&quot;&gt;태그&lt;/div&gt;
&lt;div class=&quot;magazine_tag_content&quot;&gt;#센과치히로의행방불명 #예술의전당 #오리지널투어 #공연후기 #카와에이리나 #아쿠츠니치카 #타카하시히토미 #지브리공연 #존케어드연출 #내한공연&lt;/div&gt;
&lt;div class=&quot;magazine_tag_content&quot;&gt;뮤지컬센과치히로, 센과치히로연극후기, 예술의전당오페라극장, 센과치히로굿즈, 하쿠명대사, 치히로명대사, 지브리내한공연, 서울역낙지비빔국수, 울산출발서울공연, 센과치히로캐스팅&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>내한공연</category>
      <category>뮤지컬</category>
      <category>센과치히로의행방불명</category>
      <category>애니메이션</category>
      <category>연극</category>
      <category>예술의전당</category>
      <category>오케스트라공연</category>
      <category>지브리내한공연</category>
      <category>지브리스튜디오</category>
      <category>히사히시조</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/574</guid>
      <comments>https://odinbox.tistory.com/574#entry574comment</comments>
      <pubDate>Mon, 2 Mar 2026 01:59:51 +0900</pubDate>
    </item>
    <item>
      <title>애플 맥 개발환경  설정방법</title>
      <link>https://odinbox.tistory.com/573</link>
      <description>&lt;div id=&quot;macsettings_post_wrap&quot; class=&quot;macsettings_post_wrap&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/efdu68/dJMcacoATZu/WK0Oa6z7ahiFX3Wy85QB2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/efdu68/dJMcacoATZu/WK0Oa6z7ahiFX3Wy85QB2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/efdu68/dJMcacoATZu/WK0Oa6z7ahiFX3Wy85QB2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fefdu68%2FdJMcacoATZu%2FWK0Oa6z7ahiFX3Wy85QB2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;style&gt;
    .macsettings_post_wrap{
      max-width: 960px;
      margin: 0 auto;
      padding: 20px 16px 48px;
      font-family: &quot;Pretendard&quot;,&quot;Noto Sans KR&quot;,&quot;Apple SD Gothic Neo&quot;,&quot;Malgun Gothic&quot;,sans-serif;
      color: #111827;
      line-height: 1.85;
      word-break: keep-all;
    }
    .macsettings_post_wrap *{ box-sizing: border-box; }

    .macsettings_hero{
      border: 1px solid #e5e7eb;
      border-radius: 18px;
      background: linear-gradient(135deg, #f8fbff 0%, #ffffff 45%, #f4f7fb 100%);
      padding: 22px 18px;
      margin-bottom: 18px;
    }
    .macsettings_badges{
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      margin-bottom:10px;
    }
    .macsettings_badge{
      display:inline-flex;
      align-items:center;
      padding:5px 10px;
      border-radius:999px;
      border:1px solid #e5e7eb;
      background:#fff;
      color:#374151;
      font-size:12px;
      font-weight:600;
    }
    .macsettings_title{
      margin:0 0 8px 0;
      font-size:1.85rem;
      line-height:1.35;
      letter-spacing:-0.02em;
      color:#0f172a;
    }
    .macsettings_subtitle{
      margin:0;
      color:#4b5563;
      font-size:0.98rem;
    }

    .macsettings_section{
      margin-top:30px;
    }
    .macsettings_section h2{
      margin:0 0 12px;
      font-size:1.33rem;
      line-height:1.4;
      color:#0f172a;
      border-left:5px solid #2563eb;
      padding-left:10px;
      letter-spacing:-0.01em;
    }
    .macsettings_section h3{
      margin:18px 0 8px;
      font-size:1.03rem;
      color:#1f2937;
    }
    .macsettings_section p{
      margin:10px 0;
      color:#1f2937;
    }
    .macsettings_section ul{
      margin:8px 0 12px;
      padding-left:20px;
    }
    .macsettings_section li{
      margin:4px 0;
    }

    .macsettings_callout{
      margin:14px 0;
      padding:12px 14px;
      border-radius:12px;
      border:1px solid #dbeafe;
      background:#eff6ff;
      color:#1e3a8a;
      font-size:0.95rem;
    }
    .macsettings_callout_warn{
      border-color:#fde68a;
      background:#fffbeb;
      color:#92400e;
    }
    .macsettings_callout_ok{
      border-color:#bbf7d0;
      background:#f0fdf4;
      color:#166534;
    }

    .macsettings_table_wrap{
      overflow-x:auto;
      margin:12px 0 16px;
      border:1px solid #e5e7eb;
      border-radius:12px;
      background:#fff;
    }
    .macsettings_table{
      width:100%;
      min-width:640px;
      border-collapse:collapse;
      font-size:0.93rem;
    }
    .macsettings_table th,
    .macsettings_table td{
      padding:10px 12px;
      border-bottom:1px solid #f1f5f9;
      text-align:left;
      vertical-align:top;
    }
    .macsettings_table th{
      background:#f8fafc;
      color:#0f172a;
      font-weight:700;
    }

    .macsettings_code{
      margin:12px 0;
      border:1px solid #e5e7eb;
      border-radius:12px;
      background:#0f172a;
      color:#e5e7eb;
      padding:12px 14px;
      overflow-x:auto;
      font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, &quot;Liberation Mono&quot;, monospace;
      font-size:0.9rem;
      line-height:1.6;
    }
    .macsettings_code pre{
      margin:0;
      white-space:pre;
    }

    .macsettings_checklist{
      margin:12px 0;
      padding:12px 14px;
      border:1px solid #e5e7eb;
      border-radius:12px;
      background:#fff;
    }
    .macsettings_checklist_title{
      margin:0 0 8px 0;
      font-weight:700;
      color:#111827;
      font-size:0.95rem;
    }
    .macsettings_checklist ul{
      margin:0;
      padding-left:18px;
    }

    .macsettings_kpi_grid{
      display:grid;
      grid-template-columns:repeat(2, minmax(0,1fr));
      gap:10px;
      margin:14px 0 6px;
    }
    .macsettings_kpi_card{
      border:1px solid #e5e7eb;
      border-radius:12px;
      padding:12px;
      background:#fff;
    }
    .macsettings_kpi_label{
      font-size:0.82rem;
      color:#6b7280;
      margin-bottom:4px;
    }
    .macsettings_kpi_value{
      font-size:1rem;
      font-weight:700;
      color:#111827;
      line-height:1.4;
    }

    .macsettings_reference{
      margin-top:30px;
      padding-top:16px;
      border-top:1px dashed #d1d5db;
    }
    .macsettings_reference h2{
      border-left-color:#64748b;
    }
    .macsettings_reference ul{
      margin:8px 0 0;
      padding-left:18px;
    }
    .macsettings_reference li{
      margin:6px 0;
      color:#374151;
    }

    .macsettings_tags{
      margin-top:24px;
      display:flex;
      flex-wrap:wrap;
      gap:8px;
    }
    .macsettings_tag{
      display:inline-flex;
      align-items:center;
      border:1px solid #dbeafe;
      background:#eff6ff;
      color:#1d4ed8;
      border-radius:999px;
      padding:6px 10px;
      font-size:0.86rem;
      font-weight:600;
    }

    .macsettings_footer_note{
      margin-top:20px;
      color:#6b7280;
      font-size:0.9rem;
    }

    .macsettings_terminal_cards_wrap{
      margin: 14px 0 8px;
    }
    .macsettings_terminal_grid{
      display:grid;
      grid-template-columns: repeat(3, minmax(0,1fr));
      gap:12px;
      margin-top:12px;
    }
    .macsettings_terminal_card{
      border:1px solid #e5e7eb;
      border-radius:14px;
      background:#fff;
      overflow:hidden;
      box-shadow: 0 1px 2px rgba(15,23,42,0.04);
    }
    .macsettings_terminal_card_head{
      padding:12px 14px;
      border-bottom:1px solid #eef2f7;
      background:#f8fafc;
    }
    .macsettings_terminal_card_title{
      margin:0;
      font-size:1rem;
      font-weight:800;
      color:#0f172a;
      letter-spacing:-0.01em;
    }
    .macsettings_terminal_card_sub{
      margin:4px 0 0;
      font-size:0.85rem;
      color:#64748b;
    }
    .macsettings_terminal_card_body{
      padding:12px 14px;
    }
    .macsettings_terminal_metric{
      display:flex;
      justify-content:space-between;
      align-items:flex-start;
      gap:8px;
      padding:8px 0;
      border-bottom:1px dashed #eef2f7;
    }
    .macsettings_terminal_metric:last-child{
      border-bottom:none;
      padding-bottom:0;
    }
    .macsettings_terminal_metric_key{
      font-size:0.88rem;
      color:#475569;
      min-width:100px;
      flex:0 0 100px;
    }
    .macsettings_terminal_metric_val{
      font-size:0.9rem;
      color:#111827;
      font-weight:600;
      text-align:right;
      line-height:1.4;
    }
    .macsettings_terminal_badges{
      display:flex;
      flex-wrap:wrap;
      gap:6px;
      margin-top:12px;
    }
    .macsettings_terminal_badge{
      display:inline-flex;
      align-items:center;
      padding:4px 8px;
      border-radius:999px;
      font-size:0.78rem;
      font-weight:700;
      border:1px solid #e5e7eb;
      background:#fff;
      color:#334155;
    }
    .macsettings_terminal_bestfor{
      margin-top:12px;
      padding:10px 11px;
      border-radius:10px;
      border:1px solid #e5e7eb;
      background:#fafafa;
      font-size:0.86rem;
      color:#334155;
      line-height:1.5;
    }
    .macsettings_terminal_bestfor strong{
      color:#111827;
    }
    .macsettings_terminal_compare_note{
      margin-top:12px;
      padding:12px 14px;
      border-radius:12px;
      border:1px solid #dbeafe;
      background:#eff6ff;
      color:#1e3a8a;
      font-size:0.93rem;
    }
    .macsettings_terminal_benchmark_box{
      margin-top:14px;
      border:1px solid #e5e7eb;
      border-radius:12px;
      background:#fff;
      padding:12px 14px;
    }
    .macsettings_terminal_benchmark_box h4{
      margin:0 0 8px;
      font-size:0.96rem;
      color:#0f172a;
    }
    .macsettings_terminal_benchmark_box ul{
      margin:0;
      padding-left:18px;
    }
    .macsettings_terminal_benchmark_box li{
      margin:4px 0;
      font-size:0.92rem;
      color:#334155;
    }

    @media (max-width: 980px){
      .macsettings_terminal_grid{
        grid-template-columns:1fr;
      }
      .macsettings_terminal_metric_key{
        flex:0 0 88px;
        min-width:88px;
      }
    }

    @media (max-width: 768px){
      .macsettings_title{ font-size:1.5rem; }
      .macsettings_kpi_grid{ grid-template-columns:1fr; }
      .macsettings_post_wrap{ padding:14px 12px 36px; }
    }
  &lt;/style&gt;
&lt;div class=&quot;macsettings_hero&quot;&gt;
&lt;div class=&quot;macsettings_badges&quot;&gt;&lt;span class=&quot;macsettings_badge&quot;&gt;2026 맥 개발환경&lt;/span&gt; &lt;span class=&quot;macsettings_badge&quot;&gt;Apple Silicon&lt;/span&gt; &lt;span class=&quot;macsettings_badge&quot;&gt;실사용 후기형 정리&lt;/span&gt; &lt;span class=&quot;macsettings_badge&quot;&gt;AI Agent Workflow&lt;/span&gt;&lt;/div&gt;
&lt;p class=&quot;macsettings_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;최근 맥북을 새로 구매하고 처음 세팅하면서 직접 겪은 시행착오를 바탕으로, 개발자가 실제로 바로 적용할 수 있는 기준으로 정리한 실전 가이드입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;section id=&quot;macsettings_intro&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;맥북 사고 세팅하면서 제일 많이 헤맸던 부분들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥북을 최근에 새로 샀습니다. 처음에는 금방 끝날 줄 알았는데, 막상 세팅해보니 생각보다 시간이 많이 걸렸습니다. 정보는 많은데, 인텔 맥 기준 글과 Apple Silicon 기준 글이 섞여 있고, 도구 추천은 많은데 왜 그 조합이 좋은지 설명이 부족한 경우가 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 처음 세팅할 때 막혔던 포인트는 비슷했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Homebrew 설치 경로와 PATH 설정&lt;/li&gt;
&lt;li&gt;터미널 선택 (Ghostty / iTerm2 / Warp)&lt;/li&gt;
&lt;li&gt;VSCode + 터미널 + AI 도구 조합 정리&lt;/li&gt;
&lt;li&gt;프로젝트별 런타임 버전 관리(asdf / direnv)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이 글은 단순히 &amp;ldquo;좋은 앱 모음&amp;rdquo;이 아니라, &lt;b&gt;처음부터 다시 깔끔하게 잡는 맥 개발환경 기준&lt;/b&gt;을 성능 / 생산성 / 유지보수성 관점에서 한 번에 정리한 글입니다.&lt;/p&gt;
&lt;div class=&quot;macsettings_callout&quot;&gt;이 글의 목표는 &amp;ldquo;많이 설치하는 것&amp;rdquo;이 아니라 &amp;ldquo;덜 꼬이고 오래 쓰는 개발환경&amp;rdquo;입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_1&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 개발하기 전에 먼저 바꾼 macOS 기본 설정들&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;타이핑/커서 이동이 답답해서 가장 먼저 손본 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 하루에 타이핑과 커서 이동을 정말 많이 합니다. 그래서 macOS 기본값보다 키 반복 속도와 반복 지연 시간을 개발자 기준으로 조정해두는 게 체감 차이가 큽니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;키 반복 속도 : 빠르게&lt;/li&gt;
&lt;li&gt;반복 지연 시간 : 짧게&lt;/li&gt;
&lt;li&gt;자동 수정 / 자동 대문자 / 인라인 텍스트 예측 : 비활성화 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;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;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;Dock 자동 숨김&lt;/li&gt;
&lt;li&gt;창 전환/배치 습관화 (Raycast와 같이 쓰면 더 좋음)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;macsettings_callout macsettings_callout_ok&quot;&gt;먼저 이 기본 설정을 잡아두면 이후 도구 세팅보다 먼저 &amp;ldquo;작업 감각&amp;rdquo;이 좋아집니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_2&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 애플 실리콘 맥에서 Homebrew부터 제대로 잡아야 하는 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple Silicon 맥에서는 개발환경의 시작점이 거의 Homebrew라고 봐도 됩니다. 여기서 경로/PATH를 잘못 잡으면 이후 설치되는 도구들도 연쇄적으로 꼬일 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;필수 선행 : Xcode Command Line Tools 설치&lt;/h3&gt;
&lt;div class=&quot;macsettings_code&quot;&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;xcode-select --install&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Apple Silicon 기준 Homebrew 경로 체크&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인텔 맥 시절 글과 달리, Apple Silicon 기준 Homebrew 기본 경로는 &lt;code&gt;/opt/homebrew&lt;/code&gt; 입니다. 예전 글 그대로 따라가면 여기서 헷갈리기 쉽습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PATH 설정 (처음 세팅할 때 가장 자주 놓치는 부분)&lt;/h3&gt;
&lt;div class=&quot;macsettings_code&quot;&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_table_wrap&quot;&gt;
&lt;table class=&quot;macsettings_table&quot; 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;실무 체크 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;설치 경로&lt;/td&gt;
&lt;td&gt;/opt/homebrew&lt;/td&gt;
&lt;td&gt;Apple Silicon 기준 경로 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;선행 도구&lt;/td&gt;
&lt;td&gt;Xcode Command Line Tools&lt;/td&gt;
&lt;td&gt;brew 설치 전 선행 권장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;환경 변수&lt;/td&gt;
&lt;td&gt;brew shellenv 등록&lt;/td&gt;
&lt;td&gt;.zprofile 반영 후 새 셸 재실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;정상 확인&lt;/td&gt;
&lt;td&gt;brew --version / which brew&lt;/td&gt;
&lt;td&gt;경로가 /opt/homebrew인지 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_callout macsettings_callout_warn&quot;&gt;처음부터 패키지를 많이 깔기보다, brew 경로 인식과 PATH부터 정상인지 확인하고 진행하는 게 안전합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_3&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 터미널 뭘 써야 할지 고민될 때, Ghostty vs iTerm2 vs Warp&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 세팅에서 가장 오래 고민한 부분 중 하나가 터미널이었습니다. 예전에는 iTerm2를 기본처럼 썼는데, 요즘은 Ghostty/Warp처럼 성격이 확실히 다른 선택지가 생겨서 &amp;ldquo;무엇을 기준으로 고를지&amp;rdquo;부터 다시 정리할 필요가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 비교할 때 본 기준은 기능 개수보다 아래 항목들이었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 반응성 (타이핑 지연 체감)&lt;/li&gt;
&lt;li&gt;대용량 로그 출력/스크롤 안정성&lt;/li&gt;
&lt;li&gt;다중 탭/분할창 사용 시 부하&lt;/li&gt;
&lt;li&gt;tmux 사용 비중&lt;/li&gt;
&lt;li&gt;AI 기능 통합 필요 여부&lt;/li&gt;
&lt;li&gt;설정 방식 취향 (GUI vs 설정파일)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;macsettings_terminal_cards_wrap&quot;&gt;
&lt;div class=&quot;macsettings_terminal_grid&quot;&gt;
&lt;article class=&quot;macsettings_terminal_card&quot;&gt;
&lt;div class=&quot;macsettings_terminal_card_head&quot;&gt;
&lt;h3 class=&quot;macsettings_terminal_card_title&quot; data-ke-size=&quot;size23&quot;&gt;Ghostty&lt;/h3&gt;
&lt;p class=&quot;macsettings_terminal_card_sub&quot; data-ke-size=&quot;size16&quot;&gt;고성능 &amp;middot; 저지연 &amp;middot; 미니멀 지향&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_card_body&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;핵심 포지션&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;성능/반응성 중심 터미널&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;입력 반응성&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;매우 빠름 (체감 우수)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;로그 처리&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;대용량 출력/스크롤에 강점&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;설정 방식&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;설정 파일 기반&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;AI 관점&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;외부 도구 연동 중심&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_badges&quot;&gt;&lt;span class=&quot;macsettings_terminal_badge&quot;&gt;성능 우선&lt;/span&gt; &lt;span class=&quot;macsettings_terminal_badge&quot;&gt;로그 작업&lt;/span&gt; &lt;span class=&quot;macsettings_terminal_badge&quot;&gt;미니멀&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_bestfor&quot;&gt;&lt;b&gt;추천 시나리오 :&lt;/b&gt; 빌드 로그 / 스트리밍 로그를 오래 보고, 입력 반응성과 스크롤 부드러움을 중요하게 보는 개발자&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;article class=&quot;macsettings_terminal_card&quot;&gt;
&lt;div class=&quot;macsettings_terminal_card_head&quot;&gt;
&lt;h3 class=&quot;macsettings_terminal_card_title&quot; data-ke-size=&quot;size23&quot;&gt;iTerm2&lt;/h3&gt;
&lt;p class=&quot;macsettings_terminal_card_sub&quot; data-ke-size=&quot;size16&quot;&gt;기능 풍부 &amp;middot; 검증된 워크플로우 &amp;middot; 안정성&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_card_body&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;핵심 포지션&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;전통 강자 / 기능 중심&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;입력 반응성&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;안정적 (검증된 사용감)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;로그 처리&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;무난~좋음 (설정 영향 큼)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;설정 방식&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;GUI 기반 (세부 설정 강함)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;AI 관점&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;외부 도구 연동 중심&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_badges&quot;&gt;&lt;span class=&quot;macsettings_terminal_badge&quot;&gt;안정성&lt;/span&gt; &lt;span class=&quot;macsettings_terminal_badge&quot;&gt;GUI 설정&lt;/span&gt; &lt;span class=&quot;macsettings_terminal_badge&quot;&gt;tmux 친화&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_bestfor&quot;&gt;&lt;b&gt;추천 시나리오 :&lt;/b&gt; tmux/서버 운영 비중이 높고, 기능 많은 터미널에 익숙한 파워 유저&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;article class=&quot;macsettings_terminal_card&quot;&gt;
&lt;div class=&quot;macsettings_terminal_card_head&quot;&gt;
&lt;h3 class=&quot;macsettings_terminal_card_title&quot; data-ke-size=&quot;size23&quot;&gt;Warp&lt;/h3&gt;
&lt;p class=&quot;macsettings_terminal_card_sub&quot; data-ke-size=&quot;size16&quot;&gt;AI 중심 &amp;middot; 앱형 UX &amp;middot; 생산성 워크플로우&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_card_body&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;핵심 포지션&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;AI 중심 생산성 터미널&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;입력 반응성&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;빠른 편 (기능 레이어 영향 가능)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;로그 처리&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;무난 (환경/설정 의존)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;설정 방식&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;앱형 UI / 입문 쉬움&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric&quot;&gt;
&lt;div class=&quot;macsettings_terminal_metric_key&quot;&gt;AI 관점&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_metric_val&quot;&gt;내장형 경험 강점&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_badges&quot;&gt;&lt;span class=&quot;macsettings_terminal_badge&quot;&gt;AI 보조&lt;/span&gt; &lt;span class=&quot;macsettings_terminal_badge&quot;&gt;생산성 UX&lt;/span&gt; &lt;span class=&quot;macsettings_terminal_badge&quot;&gt;입문 쉬움&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_bestfor&quot;&gt;&lt;b&gt;추천 시나리오 :&lt;/b&gt; 명령어 탐색/실행과 AI 보조를 함께 쓰고, 터미널을 생산성 앱처럼 활용하는 워크플로우&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_compare_note&quot;&gt;제 기준 결론 : &lt;b&gt;Ghostty는 성능/반응성&lt;/b&gt;, &lt;b&gt;iTerm2는 기능/안정성&lt;/b&gt;, &lt;b&gt;Warp는 AI 중심 UX&lt;/b&gt;가 확실히 다르게 느껴졌습니다. 무조건 하나가 최고라기보다, 내 작업 비중(로그/운영/AI보조)에 따라 선택하는 게 맞았습니다.&lt;/div&gt;
&lt;div class=&quot;macsettings_terminal_benchmark_box&quot;&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;빠른 타이핑 시 입력 지연 체감 여부&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker logs -f&lt;/code&gt;, &lt;code&gt;kubectl logs -f&lt;/code&gt; 스트리밍 시 스크롤 끊김 여부&lt;/li&gt;
&lt;li&gt;탭 10개 이상 + 분할창 사용 시 부하/전환 속도&lt;/li&gt;
&lt;li&gt;tmux 사용 시 단축키 충돌/워크플로우 적합성&lt;/li&gt;
&lt;li&gt;장시간 실행 시 안정성 및 메모리 증가 체감&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_4&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. zsh 꾸미기보다 먼저 한 생산성 자동화 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;zsh 설정은 예쁘게 꾸미는 것보다 먼저, 반복 작업을 줄이는 방향으로 잡는 게 체감이 큽니다. 저는 프롬프트/플러그인을 최소화하고 alias/함수 위주로 먼저 정리했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추천 구성 (과하지 않게)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Oh-My-Zsh (기반)&lt;/li&gt;
&lt;li&gt;Powerlevel10k (프롬프트 정보 가시성)&lt;/li&gt;
&lt;li&gt;fzf (탐색 속도 개선)&lt;/li&gt;
&lt;li&gt;zsh-autosuggestions (명령어 오타/반복 입력 감소)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실제로 자주 쓰게 된 alias / 함수 예시&lt;/h3&gt;
&lt;div class=&quot;macsettings_code&quot;&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;alias p=&quot;pnpm&quot;
alias s=&quot;source ~/.zshrc&quot;
alias cz=&quot;code ~/.zshrc&quot;
alias e=&quot;exit&quot;

killport() {
  lsof -i tcp:&quot;$1&quot; | awk 'NR!=1 {print $2}' | xargs kill -9
}

gfm() {
  git fetch origin main &amp;amp;&amp;amp; git merge origin/main
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_callout&quot;&gt;포인트는 &amp;ldquo;멋있는 셸&amp;rdquo;이 아니라 &amp;ldquo;자주 반복하는 명령어를 줄이는 셸&amp;rdquo;입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_5&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 요즘 맥 개발환경에서 AI 도구를 붙이면 달라지는 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에는 AI 도구가 코드 자동완성 중심이었다면, 요즘은 작업 흐름 자체를 도와주는 쪽으로 많이 바뀌었습니다. 특히 터미널/에디터와 연결되는 에이전트형 도구를 붙이면 반복 작업이나 탐색 비용이 줄어드는 체감이 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Kiro CLI를 좁은 범위부터 붙이면 좋았던 이유&lt;/h3&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;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;설치 예시&lt;/h3&gt;
&lt;div class=&quot;macsettings_code&quot;&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;curl -fsSL https://cli.kiro.dev/install | bash&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_callout macsettings_callout_warn&quot;&gt;처음부터 모든 작업을 AI에게 맡기기보다, &amp;ldquo;탐색/초안/반복작업&amp;rdquo;처럼 검증 가능한 영역부터 붙이는 방식이 실무에서 더 안전합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_6&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. VSCode + Raycast 조합이 생각보다 큰 차이를 만든 이유&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;VSCode : 확장보다 먼저 정리할 것&lt;/h3&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;Settings Sync로 환경 재현성 확보&lt;/li&gt;
&lt;li&gt;&lt;code&gt;code .&lt;/code&gt; 실행 가능한 PATH 구성&lt;/li&gt;
&lt;li&gt;macOS 단축키 충돌 점검&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Raycast : 단순 실행기보다 작업 허브로 사용&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Window Management&lt;/li&gt;
&lt;li&gt;Clipboard History&lt;/li&gt;
&lt;li&gt;비밀번호 관리자 연동(Bitwarden / 1Password)&lt;/li&gt;
&lt;li&gt;단축키 중심 앱 전환&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;macsettings_kpi_grid&quot;&gt;
&lt;div class=&quot;macsettings_kpi_card&quot;&gt;
&lt;div class=&quot;macsettings_kpi_label&quot;&gt;체감 포인트 1&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_value&quot;&gt;도구 전환 시간 감소&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_card&quot;&gt;
&lt;div class=&quot;macsettings_kpi_label&quot;&gt;체감 포인트 2&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_value&quot;&gt;마우스 의존도 감소&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_card&quot;&gt;
&lt;div class=&quot;macsettings_kpi_label&quot;&gt;체감 포인트 3&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_value&quot;&gt;반복 작업 흐름 고정&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_card&quot;&gt;
&lt;div class=&quot;macsettings_kpi_label&quot;&gt;체감 포인트 4&lt;/div&gt;
&lt;div class=&quot;macsettings_kpi_value&quot;&gt;맥락 전환 비용 감소&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_7&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 프로젝트마다 버전 달라서 꼬일 때 해결한 방식 (asdf + direnv)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트마다 Node/Python/Java/.NET SDK 버전이 다르면 환경이 쉽게 꼬입니다. 이때 asdf + direnv 조합은 &amp;ldquo;내 PC에서는 되는데?&amp;rdquo; 문제를 줄이는 데 꽤 도움이 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;asdf : 런타임 버전 통합 관리&lt;/h3&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;code&gt;.tool-versions&lt;/code&gt; 파일로 팀 공유 가능&lt;/li&gt;
&lt;li&gt;프로젝트별 버전 고정에 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;direnv : 프로젝트별 환경 변수 자동 로드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디렉토리 진입 시 &lt;code&gt;.envrc&lt;/code&gt; 자동 로드&lt;/li&gt;
&lt;li&gt;쉘 이탈 시 자동 언로드&lt;/li&gt;
&lt;li&gt;프로젝트별 API 키/DB 정보 분리에 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;macsettings_callout&quot;&gt;버전 관리(asdf) + 환경 변수 관리(direnv)를 분리하면 유지보수성이 좋아지고, 프로젝트 이동도 훨씬 편해집니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_body_8&quot; class=&quot;macsettings_section&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 맥에서 .NET 개발할 때 버전/패치를 더 자주 봐야 하는 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥 기반 .NET 개발자는 로컬 SDK/런타임 상태를 주기적으로 점검하는 습관이 중요합니다. 특히 팀/서버 환경과 버전 차이가 나면, 로컬에서는 잘 되는데 배포 후 문제 나는 경우가 생기기 쉽습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2026년 기준 체크 포인트 (운영 관점)&lt;/h3&gt;
&lt;div class=&quot;macsettings_table_wrap&quot;&gt;
&lt;table class=&quot;macsettings_table&quot; 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;패치 예시 (2026-02 기준)&lt;/th&gt;
&lt;th&gt;실무 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.NET 10&lt;/td&gt;
&lt;td&gt;LTS (Active)&lt;/td&gt;
&lt;td&gt;10.0.3&lt;/td&gt;
&lt;td&gt;신규/장기 운영 검토&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET 9&lt;/td&gt;
&lt;td&gt;STS (Active)&lt;/td&gt;
&lt;td&gt;9.0.13&lt;/td&gt;
&lt;td&gt;기능 활용 + 정기 패치 필수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET 8&lt;/td&gt;
&lt;td&gt;LTS (Active)&lt;/td&gt;
&lt;td&gt;8.0.24&lt;/td&gt;
&lt;td&gt;안정 운영 환경에 적합&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;macsettings_checklist&quot;&gt;
&lt;p class=&quot;macsettings_checklist_title&quot; data-ke-size=&quot;size16&quot;&gt;실무에서 바로 적용하기 좋은 운영 습관&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;global.json으로 SDK 버전 고정&lt;/li&gt;
&lt;li&gt;월 1회 이상 SDK/런타임 점검&lt;/li&gt;
&lt;li&gt;로컬/CI/서버 버전 차이 확인 루틴 만들기&lt;/li&gt;
&lt;li&gt;보안 패치 포함 릴리스 노트 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_outro&quot; class=&quot;macsettings_section&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;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;반응성 최적화&lt;/b&gt; : 입력 지연과 창 전환 비용 줄이기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;관리 가능한 환경&lt;/b&gt; : Homebrew + asdf + direnv로 일관성 확보&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지능형 워크플로우&lt;/b&gt; : Ghostty + AI 도구 + VSCode/Raycast 조합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 맥 개발환경을 세팅하는 분들에게는 기본 틀로, 이미 사용 중인 분들에게는 환경 점검 체크리스트로 도움이 되었으면 좋겠습니다. 저도 이후에는 실제로 쓰는 dotfiles와 프로젝트 템플릿 기준으로 더 구체적인 세팅 글을 이어서 정리해볼 생각입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;macsettings_refs&quot; class=&quot;macsettings_section macsettings_reference&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;Homebrew 공식 설치/설정 문서 (Apple Silicon 경로 및 shellenv 기준 확인)&lt;/li&gt;
&lt;li&gt;Ghostty 공식 문서 (macOS 기능 및 렌더링 관련 내용 확인)&lt;/li&gt;
&lt;li&gt;Kiro CLI 공식 사이트/CLI 설치 문서&lt;/li&gt;
&lt;li&gt;.NET 공식 다운로드 / 릴리스 정보 (8/9/10 버전 및 패치 확인)&lt;/li&gt;
&lt;li&gt;Raycast 공식 문서 (확장/단축키 운영 참고)&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;macsettings_footer_note&quot; data-ke-size=&quot;size16&quot;&gt;버전/설치 명령/패치 정보는 시점에 따라 변동될 수 있으므로, 실제 적용 전 공식 문서를 기준으로 최종 확인하는 것을 권장합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&quot;macsettings_tags&quot; aria-label=&quot;태그&quot;&gt;&lt;span class=&quot;macsettings_tag&quot;&gt;#맥북개발환경&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#AppleSilicon&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#MacOS최적화&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#Homebrew&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#Ghostty&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#iTerm2&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#Warp&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#KiroCLI&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#VSCode세팅&lt;/span&gt; &lt;span class=&quot;macsettings_tag&quot;&gt;#닷넷개발환경&lt;/span&gt;&lt;/div&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
  {
    &quot;@context&quot;:&quot;https://schema.org&quot;,
    &quot;@type&quot;:&quot;BlogPosting&quot;,
    &quot;headline&quot;:&quot;2026년형 애플 실리콘 맥 개발환경 세팅 완전정리 : Homebrew·Ghostty·Kiro CLI·VSCode·.NET 최적화 전략&quot;,
    &quot;description&quot;:&quot;최근 맥북을 새로 구매하고 처음 세팅하면서 겪은 시행착오를 바탕으로, Apple Silicon 맥 개발환경을 성능·생산성·유지보수성 기준으로 정리한 실전 가이드.&quot;,
    &quot;keywords&quot;:[&quot;맥북 개발환경&quot;,&quot;Apple Silicon&quot;,&quot;Homebrew&quot;,&quot;Ghostty&quot;,&quot;iTerm2&quot;,&quot;Warp&quot;,&quot;Kiro CLI&quot;,&quot;VSCode&quot;,&quot;.NET&quot;,&quot;asdf&quot;,&quot;direnv&quot;],
    &quot;inLanguage&quot;:&quot;ko-KR&quot;
  }
  &lt;/script&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>homebrew</category>
      <category>MacOS</category>
      <category>개발자</category>
      <category>개발환경</category>
      <category>맥북</category>
      <category>설정방법</category>
      <category>애플</category>
      <category>윈도우</category>
      <category>초보</category>
      <category>터미널</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/573</guid>
      <comments>https://odinbox.tistory.com/573#entry573comment</comments>
      <pubDate>Sun, 1 Mar 2026 10:20:41 +0900</pubDate>
    </item>
    <item>
      <title>카카오맵 + OSRM 연동 경로 탐색 및 폴리라인 구현 방법</title>
      <link>https://odinbox.tistory.com/572</link>
      <description>&lt;div&gt;
&lt;style&gt;
  .osrm-post{
    max-width:980px;
    margin:0 auto;
    padding:8px 4px 28px;
    color:#111827;
    font-family:&quot;Pretendard&quot;,&quot;Noto Sans KR&quot;,&quot;Apple SD Gothic Neo&quot;,&quot;Malgun Gothic&quot;,sans-serif;
    line-height:1.85;
    word-break:keep-all;
  }
  .osrm-post *{box-sizing:border-box;}
  .osrm-post .hero{
    border:1px solid #e5e7eb;
    background:linear-gradient(135deg,#eff6ff 0%, #ffffff 55%, #f8fafc 100%);
    border-radius:16px;
    padding:20px 18px;
    margin:4px 0 14px;
  }
  .osrm-post .badge-wrap{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px;}
  .osrm-post .badge{
    display:inline-flex;align-items:center;
    padding:5px 10px;border-radius:999px;border:1px solid #e5e7eb;
    background:#fff;color:#4b5563;font-size:12px;
  }
  .osrm-post h1{
    margin:0 0 10px;
    font-size:26px;line-height:1.35;letter-spacing:-0.02em;
    color:#0f172a;
  }
  .osrm-post .lead{
    margin:0;
    color:#374151;
    font-size:15px;
  }
  .osrm-post .meta{
    margin-top:10px;
    display:flex;flex-wrap:wrap;gap:8px 12px;
    color:#6b7280;font-size:13px;
  }

  .osrm-post .hero-thumb{
    margin:0 0 18px;
    padding:10px;
    border:1px solid #e5e7eb;
    border-radius:16px;
    background:#fff;
    box-shadow:0 6px 20px rgba(15,23,42,.04);
  }
  .osrm-post .hero-thumb &gt; p{
    margin:0 !important;
    text-align:center;
  }
  .osrm-post .hero-thumb img{
    display:block;
    margin:0 auto;
    max-width:100%;
    height:auto;
    border-radius:12px;
  }

  .osrm-post h2{
    margin:34px 0 12px;
    padding-bottom:8px;
    border-bottom:2px solid #eef2f7;
    font-size:20px;
    line-height:1.45;
    letter-spacing:-0.01em;
    color:#111827;
  }
  .osrm-post h3{
    margin:22px 0 10px;
    font-size:16px;
    line-height:1.5;
    letter-spacing:-0.01em;
    color:#111827;
  }

  .osrm-post p{margin:10px 0 12px;}
  .osrm-post ul{margin:8px 0 12px;padding-left:20px;}
  .osrm-post li{margin:6px 0;}
  .osrm-post strong{color:#111827;}

  .osrm-post .inline-code{
    display:inline-block;
    background:#f3f4f6;
    border:1px solid #e5e7eb;
    border-radius:6px;
    padding:0 6px;
    font-family:Consolas,&quot;D2Coding&quot;,monospace;
    font-size:.94em;
    line-height:1.6;
  }

  .osrm-post .card{
    border:1px solid #e5e7eb;
    background:#f9fafb;
    border-radius:14px;
    padding:14px;
    margin:14px 0;
  }
  .osrm-post .callout{
    border:1px solid #bfdbfe;
    background:#eef5ff;
    border-radius:12px;
    padding:12px 14px;
    margin:14px 0;
  }
  .osrm-post .warn{
    border:1px solid #fdba74;
    background:#fff7ed;
    border-radius:12px;
    padding:12px 14px;
    margin:14px 0;
  }
  .osrm-post .good{
    border:1px solid #86efac;
    background:#f0fdf4;
    border-radius:12px;
    padding:12px 14px;
    margin:14px 0;
  }

  .osrm-post .grid-2{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:12px;
    margin:10px 0 14px;
  }
  .osrm-post .grid-2 &gt; div{
    border:1px solid #e5e7eb;
    background:#fff;
    border-radius:12px;
    padding:12px;
  }
  .osrm-post .grid-2 h4{
    margin:0 0 6px;
    font-size:14px;
    color:#111827;
  }

  .osrm-post .table-wrap{
    overflow-x:auto;
    border:1px solid #e5e7eb;
    border-radius:12px;
    background:#fff;
    margin:12px 0 14px;
  }
  .osrm-post table{
    width:100%;
    min-width:720px;
    border-collapse:collapse;
    font-size:14px;
  }
  .osrm-post th, .osrm-post td{
    text-align:left;
    vertical-align:top;
    padding:10px 10px;
    border-bottom:1px solid #e5e7eb;
  }
  .osrm-post th{
    background:#f8fafc;
    font-weight:700;
  }

  .osrm-post hr{
    border:0;
    border-top:1px solid #e5e7eb;
    margin:28px 0;
  }

  .osrm-post details.faq{
    border:1px solid #e5e7eb;
    border-radius:12px;
    background:#fff;
    margin:10px 0;
    overflow:hidden;
  }
  .osrm-post details.faq summary{
    cursor:pointer;
    list-style:none;
    padding:12px 14px;
    font-weight:700;
    background:#f9fafb;
    border-bottom:1px solid #e5e7eb;
  }
  .osrm-post details.faq summary::-webkit-details-marker{display:none;}
  .osrm-post details.faq .faq-body{padding:12px 14px;}

  .osrm-post .foot{
    border:1px solid #e5e7eb;
    border-radius:14px;
    background:linear-gradient(180deg,#fff,#f8fafc);
    padding:14px;
    margin-top:16px;
  }
  .osrm-post .kv{
    display:grid;
    grid-template-columns:120px 1fr;
    gap:6px 10px;
    font-size:14px;
  }
  .osrm-post .kv div:nth-child(odd){
    color:#6b7280;
    font-weight:600;
  }

  @media (max-width:768px){
    .osrm-post{padding:6px 2px 18px;line-height:1.75;}
    .osrm-post h1{font-size:20px;}
    .osrm-post h2{font-size:18px;}
    .osrm-post .grid-2{grid-template-columns:1fr;}
    .osrm-post .kv{grid-template-columns:1fr;}
    .osrm-post .hero-thumb{padding:8px;border-radius:14px;}
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;article class=&quot;osrm-post&quot;&gt;&lt;header class=&quot;hero&quot;&gt;
&lt;div class=&quot;badge-wrap&quot;&gt;&lt;span class=&quot;badge&quot;&gt;카카오맵 API&lt;/span&gt; &lt;span class=&quot;badge&quot;&gt;OSRM&lt;/span&gt; &lt;span class=&quot;badge&quot;&gt;경로탐색&lt;/span&gt; &lt;span class=&quot;badge&quot;&gt;Polyline&lt;/span&gt; &lt;span class=&quot;badge&quot;&gt;Docker&lt;/span&gt; &lt;span class=&quot;badge&quot;&gt;추적관리 시스템&lt;/span&gt;&lt;/div&gt;
&lt;p class=&quot;lead&quot; data-ke-size=&quot;size16&quot;&gt;실무에서 추적관리(관제) 프로그램을 개발하면서 지도 위에 자산/차량의 이동 경로를 안정적으로 표시하고, 반복적으로 경로를 계산해야 하는 요구사항이 생겼습니다. 이 과정에서 상용 길찾기 API의 비용 구조와 호출 제한, 운영 환경에서의 확장성 문제를 직접 마주했고, 그 대안으로 &lt;b&gt;카카오맵 + OSRM 조합&lt;/b&gt;을 적용했습니다.&lt;/p&gt;
&lt;div class=&quot;meta&quot;&gt;&lt;span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;핵심 포인트 : 좌표 순서 변환 + 렌더링 관리&lt;/span&gt;&lt;/span&gt; &lt;span&gt;실전 코드 : Kakao Polyline + OSRM Route API&lt;/span&gt;&lt;/div&gt;
&lt;/header&gt;&lt;!-- 상단 대표 이미지 (사용자 제공 티스토리 이미지 태그) --&gt;
&lt;div class=&quot;hero-thumb&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rkbC7/dJMcaf6Gduy/PA0eQm607ErN3aF7IpBA3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rkbC7/dJMcaf6Gduy/PA0eQm607ErN3aF7IpBA3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rkbC7/dJMcaf6Gduy/PA0eQm607ErN3aF7IpBA3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrkbC7%2FdJMcaf6Gduy%2FPA0eQm607ErN3aF7IpBA3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;card&quot;&gt;&lt;b&gt;작성 배경&lt;/b&gt;&lt;br /&gt;실제 추적관리 프로그램(위치/이동 이력 관제 성격의 시스템)을 개발하던 중, 지도 렌더링은 카카오맵으로 처리하면서 경로 계산은 비용 효율적으로 운영할 수 있는 구조가 필요했습니다. 단순 데모가 아니라 재조회, 실시간 갱신, 다회 렌더링, 운영 안정성까지 고려해야 했기 때문에 OSRM을 연동하는 방식으로 설계했고, 적용 후 구조가 안정적으로 정리되었습니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 카카오맵 + OSRM 조합을 선택했는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위치 기반 서비스(LBS), 물류, 관제, 자산 추적 시스템에서는 &lt;b&gt;출발지~목적지 경로 계산&lt;/b&gt;과 &lt;b&gt;지도 위 경로 시각화&lt;/b&gt;가 핵심 기능입니다. 하지만 상용 길 찾기 API는 호출량이 늘어날수록 비용 부담이 커지고, 대규모 트래픽 환경에서는 비용 예측이 어려워질 수 있습니다.&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회 경로 계산이 아니라, 경로 재계산, 다중 자산 모니터링, 반복 조회, 화면 갱신 등의 요구가 계속 발생합니다. 이런 환경에서는 &lt;b&gt;지도 UI와 경로 계산 엔진을 분리&lt;/b&gt;하는 설계가 운영 비용과 유지보수 측면에서 매우 유리합니다.&lt;/p&gt;
&lt;div class=&quot;callout&quot;&gt;&lt;b&gt;핵심 아키텍처 분리 전략&lt;/b&gt;&lt;br /&gt;&lt;span class=&quot;inline-code&quot;&gt;카카오맵&lt;/span&gt;은 사용자에게 친숙한 국내 지도 UI/POI/오버레이 렌더링을 담당하고, &lt;span class=&quot;inline-code&quot;&gt;OSRM&lt;/span&gt;은 경로 계산(거리/시간/최적 경로) 전담 엔진으로 사용합니다. 이렇게 분리하면 실무에서 비용, 성능, 확장성 모두 잡기 쉬워집니다.&lt;/div&gt;
&lt;div class=&quot;grid-2&quot;&gt;
&lt;div&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;국내 사용자에게 익숙한 지도 UX&lt;/li&gt;
&lt;li&gt;마커/폴리라인/오버레이 렌더링 편의성&lt;/li&gt;
&lt;li&gt;국내 서비스에 적합한 POI 표현&lt;/li&gt;
&lt;li&gt;프론트엔드 구현 속도가 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;OSRM이 좋은 이유&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;프로파일/Lua 커스터마이징 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;가장 중요한 포인트 : 좌표 순서가 다르다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오맵과 OSRM을 연동할 때 가장 많이 실수하는 부분은 &lt;b&gt;좌표 순서&lt;/b&gt;입니다. 이 부분만 정확히 이해해도 경로가 엉뚱한 위치에 찍히는 문제를 대부분 방지할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;warn&quot;&gt;&lt;b&gt;좌표 순서 규칙&lt;/b&gt;&lt;br /&gt;OSRM 입력/응답 좌표 : &lt;span class=&quot;inline-code&quot;&gt;[경도, 위도] = [lng, lat]&lt;/span&gt;&lt;br /&gt;카카오맵 LatLng 생성자 : &lt;span class=&quot;inline-code&quot;&gt;new kakao.maps.LatLng(lat, lng)&lt;/span&gt;&lt;br /&gt;즉, OSRM 좌표를 카카오맵에 넣기 전에 &lt;b&gt;순서를 뒤집어야&lt;/b&gt; 합니다.&lt;/div&gt;
&lt;div class=&quot;card&quot;&gt;&lt;b&gt;실무 팁&lt;/b&gt;&lt;br /&gt;팀 내 공통 유틸 함수(예 : &lt;span class=&quot;inline-code&quot;&gt;toKakaoLatLng(osrmCoord)&lt;/span&gt;)를 만들어두면 좌표 순서 실수를 크게 줄일 수 있습니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;OSRM Route API 요청 구조와 필수 옵션&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 Route API 호출 구조는 아래와 같습니다. 실무에서는 &lt;span class=&quot;inline-code&quot;&gt;overview&lt;/span&gt;와 &lt;span class=&quot;inline-code&quot;&gt;geometries&lt;/span&gt; 선택이 특히 중요합니다.&lt;/p&gt;
&lt;pre class=&quot;codeblock awk&quot; data-ke-language=&quot;text&quot;&gt;&lt;code&gt;GET http://{osrm-server}:{port}/route/v1/driving/{lng,lat;lng,lat}?overview=full&amp;amp;geometries=geojson&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;table-wrap&quot;&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;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;overview&lt;/td&gt;
&lt;td&gt;full&lt;/td&gt;
&lt;td&gt;도로 굴곡까지 자연스럽게 폴리라인을 그리려면 full 권장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;geometries&lt;/td&gt;
&lt;td&gt;geojson / polyline&lt;/td&gt;
&lt;td&gt;개발 편의성은 geojson, 네트워크 최적화는 polyline 유리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;steps&lt;/td&gt;
&lt;td&gt;false (기본)&lt;/td&gt;
&lt;td&gt;턴바이턴 안내가 필요할 때만 true 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;alternatives&lt;/td&gt;
&lt;td&gt;false (기본)&lt;/td&gt;
&lt;td&gt;대체 경로가 필요한 경우에만 true 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;annotations&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;h2 data-ke-size=&quot;size26&quot;&gt;GeoJSON vs Polyline 선택 기준 (실무 의사결정 포인트)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경로 geometry 응답은 &lt;span class=&quot;inline-code&quot;&gt;geometries=geojson&lt;/span&gt; 또는 &lt;span class=&quot;inline-code&quot;&gt;geometries=polyline&lt;/span&gt; 중 하나를 선택하게 됩니다. 프로젝트 단계(초기 개발/운영 확장)에 따라 선택 전략이 달라집니다.&lt;/p&gt;
&lt;div class=&quot;grid-2&quot;&gt;
&lt;div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;GeoJSON 추천 상황&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PoC, 초기 구현, 빠른 검증&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;/div&gt;
&lt;div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Polyline 추천 상황&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;OSRM 호출량이 많은 서비스&lt;/li&gt;
&lt;li&gt;클라이언트 디코딩 비용을 감수할 수 있을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;good&quot;&gt;&lt;b&gt;실무 추천 전략&lt;/b&gt;&lt;br /&gt;초기엔 &lt;span class=&quot;inline-code&quot;&gt;GeoJSON&lt;/span&gt;으로 빠르게 구현하고, 운영 트래픽이 커지면 &lt;span class=&quot;inline-code&quot;&gt;Polyline&lt;/span&gt;으로 전환하는 단계적 접근이 가장 현실적입니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;카카오맵 + OSRM 연동 실전 예제 (GeoJSON 기준)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예제는 카카오맵에 OSRM 경로를 폴리라인으로 그리는 기본 구조이면서, 실무에서 자주 필요한 &lt;b&gt;재호출 시 이전 폴리라인 제거&lt;/b&gt;, &lt;b&gt;AbortController로 요청 취소&lt;/b&gt;, &lt;b&gt;setBounds 자동 화면 맞춤&lt;/b&gt;까지 포함한 형태입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) index.html&lt;/h3&gt;
&lt;pre class=&quot;codeblock xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset=&quot;utf-8&quot; /&amp;gt;
  &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&amp;gt;
  &amp;lt;title&amp;gt;Kakao + OSRM Route Demo&amp;lt;/title&amp;gt;
  &amp;lt;style&amp;gt;
    html, body { margin:0; padding:0; height:100%; }
    #map { width:100%; height:100vh; }
    .panel{
      position:absolute; top:16px; left:16px; z-index:10;
      background:rgba(255,255,255,.96); padding:14px;
      border-radius:10px; box-shadow:0 8px 20px rgba(0,0,0,.12);
      font-family:&quot;Malgun Gothic&quot;, sans-serif;
      width:min(92vw, 380px);
    }
    .panel h3{ margin:0 0 10px; font-size:16px; }
    .panel button{
      border:0; background:#FEE500; color:#222; font-weight:700;
      border-radius:8px; padding:10px 12px; cursor:pointer;
    }
    .panel button:disabled{ opacity:.65; cursor:not-allowed; }
    #meta{ margin-top:10px; font-size:13px; color:#444; line-height:1.5; }
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div class=&quot;panel&quot;&amp;gt;
    &amp;lt;h3&amp;gt;OSRM 경로 탐색&amp;lt;/h3&amp;gt;
    &amp;lt;button id=&quot;btnRoute&quot; type=&quot;button&quot; onclick=&quot;calculateAndDrawRoute()&quot;&amp;gt;경로 계산 및 표시&amp;lt;/button&amp;gt;
    &amp;lt;p id=&quot;meta&quot;&amp;gt;버튼을 눌러 경로를 탐색하세요.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;div id=&quot;map&quot;&amp;gt;&amp;lt;/div&amp;gt;

  &amp;lt;script src=&quot;//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_KAKAO_APP_KEY&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script src=&quot;./osrm-kakao-integration.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) osrm-kakao-integration.js&lt;/h3&gt;
&lt;pre class=&quot;codeblock javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let activePolyline = null;
let startMarker = null;
let endMarker = null;
let currentAbortController = null;

const map = new kakao.maps.Map(document.getElementById('map'), {
  center : new kakao.maps.LatLng(37.382239, 127.121755),
  level : 5
});

const metaEl = document.getElementById('meta');
const btnEl = document.getElementById('btnRoute');

async function calculateAndDrawRoute() {
  // 예시 좌표 (판교역 -&amp;gt; 정자역 부근)
  const origin = { lat : 37.394726, lng : 127.111158 };
  const destination = { lat : 37.367317, lng : 127.108847 };

  // 퍼블릭 OSRM 서버 (데모/테스트용)
  // 실서비스에서는 자체 OSRM 서버 또는 백엔드 프록시 권장
  const osrmBaseUrl = 'https://router.project-osrm.org/route/v1/driving/';

  // OSRM 좌표 순서 : [lng, lat]
  const coordinatesString = `${origin.lng},${origin.lat};${destination.lng},${destination.lat}`;

  // 폴리라인 렌더링에 유리한 전체 경로 + GeoJSON
  const queryParams = '?overview=full&amp;amp;geometries=geojson&amp;amp;alternatives=false&amp;amp;steps=false';
  const requestUrl = osrmBaseUrl + coordinatesString + queryParams;

  // 이전 요청 취소 (연속 클릭/갱신 시 레이스 컨디션 방지)
  if (currentAbortController) currentAbortController.abort();
  currentAbortController = new AbortController();

  btnEl.disabled = true;
  metaEl.innerText = '경로 계산 중입니다...';

  try {
    const res = await fetch(requestUrl, { signal : currentAbortController.signal });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);

    const data = await res.json();

    if (data.code !== 'Ok' || !data.routes || data.routes.length === 0) {
      throw new Error(`OSRM error : ${data.code || 'NoRoute'}`);
    }

    const route = data.routes[0];
    const coords = route.geometry &amp;amp;&amp;amp; route.geometry.coordinates ? route.geometry.coordinates  : [];
    if (coords.length === 0) throw new Error('Empty geometry');

    const distanceKm = (route.distance / 1000).toFixed(2);
    const durationMin = Math.round(route.duration / 60);
    metaEl.innerText = `총 거리 : ${distanceKm}km / 예상 시간 : ${durationMin}분`;

    const linePath = [];
    const bounds = new kakao.maps.LatLngBounds();

    // OSRM [lng, lat] -&amp;gt; Kakao LatLng(lat, lng)
    coords.forEach(([lng, lat]) =&amp;gt; {
      const p = new kakao.maps.LatLng(lat, lng);
      linePath.push(p);
      bounds.extend(p);
    });

    // 기존 오버레이 정리 (누적 렌더링 방지)
    if (activePolyline) activePolyline.setMap(null);
    if (startMarker) startMarker.setMap(null);
    if (endMarker) endMarker.setMap(null);

    activePolyline = new kakao.maps.Polyline({
      path : linePath,
      strokeWeight : 6,
      strokeColor : '#2563EB',
      strokeOpacity : 0.9,
      strokeStyle : 'solid',
      endArrow : true
    });
    activePolyline.setMap(map);

    startMarker = new kakao.maps.Marker({ position : linePath[0], map });
    endMarker = new kakao.maps.Marker({ position : linePath[linePath.length - 1], map });

    // 경로 전체가 보이도록 자동 포커싱
    map.setBounds(bounds);

  } catch (e) {
    if (e.name === 'AbortError') return; // 이전 요청 취소는 정상 흐름
    console.error(e);
    metaEl.innerText = '오류가 발생했습니다. 콘솔 로그를 확인하세요.';
    alert('OSRM 경로 탐색/렌더링 중 오류가 발생했습니다.');
  } finally {
    btnEl.disabled = false;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;warn&quot;&gt;&lt;b&gt;운영 주의사항&lt;/b&gt;&lt;br /&gt;&lt;span class=&quot;inline-code&quot;&gt;router.project-osrm.org&lt;/span&gt;는 퍼블릭 테스트 서버이므로 상업 서비스에 그대로 사용하는 것은 권장되지 않습니다. 실서비스는 자체 OSRM 서버 또는 백엔드 프록시(BFF) 구조를 권장합니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Docker로 자체 OSRM 서버 구축하기 (실서비스 전환용)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 단계에서는 OSRM 퍼블릭 서버 대신 자체 OSRM 백엔드를 구성하는 것이 안정적입니다. 아래는 대한민국 OSM PBF 데이터를 기준으로 한 기본 구축 예시입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 대한민국 OSM 데이터 다운로드&lt;/h3&gt;
&lt;pre class=&quot;codeblock awk&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;wget http://download.geofabrik.de/asia/south-korea-latest.osm.pbf&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) OSRM 전처리 (MLD 파이프라인)&lt;/h3&gt;
&lt;pre class=&quot;codeblock dockerfile&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo docker run -t -v &quot;${PWD}:/data&quot; osrm/osrm-backend \
  osrm-extract -p /opt/car.lua /data/south-korea-latest.osm.pbf

sudo docker run -t -v &quot;${PWD}:/data&quot; osrm/osrm-backend \
  osrm-partition /data/south-korea-latest.osrm

sudo docker run -t -v &quot;${PWD}:/data&quot; osrm/osrm-backend \
  osrm-customize /data/south-korea-latest.osrm&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) OSRM 라우팅 서버 실행&lt;/h3&gt;
&lt;pre class=&quot;codeblock applescript&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo docker run -d -p 5000:5000 --name osrm-routing-server \
  -v &quot;${PWD}:/data&quot; osrm/osrm-backend \
  osrm-routed --algorithm mld /data/south-korea-latest.osrm&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;callout&quot;&gt;&lt;b&gt;실무 추천 운영 구조&lt;/b&gt;&lt;br /&gt;브라우저에서 OSRM을 직접 호출하기보다 &lt;span class=&quot;inline-code&quot;&gt;Frontend &amp;rarr; Backend(BFF/Proxy) &amp;rarr; OSRM&lt;/span&gt; 구조를 권장합니다. CORS, 인증, 로깅, 캐싱, 장애 대응, 요청 제한을 백엔드에서 통합 관리할 수 있기 때문입니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 최적화 체크리스트 (성능/안정성/유지보수)&lt;/h2&gt;
&lt;div class=&quot;card&quot;&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; OSRM = [lng,lat], Kakao = (lat,lng) 문서화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오버레이 누적 방지:&lt;/b&gt; 폴리라인/마커 재렌더링 전에 &lt;span class=&quot;inline-code&quot;&gt;setMap(null)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;요청 제어:&lt;/b&gt; AbortController + debounce/throttle 적용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;응답 최적화:&lt;/b&gt; 초기 GeoJSON, 운영 확장 시 Polyline 검토&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐싱 전략:&lt;/b&gt; 반복 경로는 백엔드 캐싱으로 OSRM 호출 절감&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예외 처리:&lt;/b&gt; NoRoute/Timeout/HTTP 오류 코드별 사용자 메시지 분리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모니터링:&lt;/b&gt; OSRM 응답시간, 오류율, 메모리 사용량 지표 수집&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;확장 기능 : 단순 경로 표시를 넘어 실무 시스템으로 확장하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추적관리 프로그램이나 물류/관제 시스템에서는 단순 A&amp;rarr;B 경로 표시를 넘어서, 다양한 라우팅/분석 기능이 필요해집니다. OSRM은 아래 기능들로 확장이 가능합니다.&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;table&lt;/b&gt; : 다대다 거리/시간 행렬 계산 (배차/순회 우선순위 계산)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;match&lt;/b&gt; : GPS 궤적 도로 스냅핑 (맵 매칭, 노이즈 보정)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;trip&lt;/b&gt; : 다중 목적지 방문 순서 최적화 (TSP 휴리스틱)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Lua 프로파일&lt;/b&gt; : 차량/이륜차/도보/특수 차량 규칙 커스터마이징&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;callout&quot;&gt;&lt;b&gt;추적관리 실무 관점에서 특히 중요한 기능&lt;/b&gt;&lt;br /&gt;GPS 위치가 흔들리는 환경에서는 &lt;span class=&quot;inline-code&quot;&gt;match&lt;/span&gt; 기반 맵 매칭이 실제 도로를 따라 움직인 것처럼 궤적 품질을 크게 개선해 줍니다.&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 문서 (공식 문서/저장소)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 문서는 실제 구현 및 운영 단계에서 자주 확인하게 되는 공식 문서들입니다. 카카오맵 SDK 사용법, OSRM Route API 옵션, 자체 OSRM 서버 구축/운영 시 기본 레퍼런스로 활용하시면 좋습니다.&lt;/p&gt;
&lt;div class=&quot;table-wrap&quot;&gt;
&lt;table style=&quot;height: 534px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 46px;&quot;&gt;
&lt;th style=&quot;width: 22%; height: 46px;&quot;&gt;구분&lt;/th&gt;
&lt;th style=&quot;width: 30%; height: 46px;&quot;&gt;문서명&lt;/th&gt;
&lt;th style=&quot;height: 46px;&quot;&gt;설명 / 활용 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 76px;&quot;&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;카카오맵&lt;/td&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;&lt;a href=&quot;https://apis.map.kakao.com/web/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; Kakao 지도 Web API (소개/시작 페이지) &lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;카카오맵 웹 API 소개, 사용 개요, 주요 기능 확인용 시작점. 앱 키 발급 후 빠르게 샘플을 확인할 때 유용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 78px;&quot;&gt;
&lt;td style=&quot;height: 78px;&quot;&gt;카카오맵&lt;/td&gt;
&lt;td style=&quot;height: 78px;&quot;&gt;&lt;a href=&quot;https://apis.map.kakao.com/web/documentation/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; Kakao 지도 Web API 문서 (클래스/메서드) &lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 78px;&quot;&gt;&lt;span class=&quot;inline-code&quot;&gt;kakao.maps.Map&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;Polyline&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;LatLng&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;LatLngBounds&lt;/span&gt; 등 실제 구현에 필요한 클래스 명세 확인용.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 76px;&quot;&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;카카오 개발자&lt;/td&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;&lt;a href=&quot;https://developers.kakao.com/docs/latest/ko/kakaomap/common&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; Kakao Developers 지도 API 시작하기 &lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;앱 등록, 플랫폼 설정(도메인 등록), 키 관리, 기본 적용 절차를 정리할 때 참고하기 좋습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 105px;&quot;&gt;
&lt;td style=&quot;height: 105px;&quot;&gt;OSRM (공식)&lt;/td&gt;
&lt;td style=&quot;height: 105px;&quot;&gt;&lt;a href=&quot;https://project-osrm.org/docs/v5.24.0/api/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; OSRM API Documentation (v5.x) &lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 105px;&quot;&gt;&lt;span class=&quot;inline-code&quot;&gt;route&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;table&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;match&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;trip&lt;/span&gt; 엔드포인트 및 &lt;span class=&quot;inline-code&quot;&gt;overview&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;geometries&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;annotations&lt;/span&gt; 등 옵션 확인용 핵심 문서.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 76px;&quot;&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;OSRM (공식 저장소)&lt;/td&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;&lt;a href=&quot;https://github.com/Project-OSRM/osrm-backend&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; Project-OSRM / osrm-backend (GitHub) &lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 76px;&quot;&gt;Docker 이미지 사용 예시, 빌드/실행 방식, 최신 변경사항 추적, 이슈/토론 확인에 유용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 77px;&quot;&gt;
&lt;td style=&quot;height: 77px;&quot;&gt;OSM 데이터&lt;/td&gt;
&lt;td style=&quot;height: 77px;&quot;&gt;&lt;a href=&quot;https://download.geofabrik.de/asia/south-korea.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; Geofabrik - South Korea OSM Extract &lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 77px;&quot;&gt;대한민국 OSM PBF 다운로드 페이지. 자체 OSRM 서버 구축 시 입력 데이터(&lt;span class=&quot;inline-code&quot;&gt;.osm.pbf&lt;/span&gt;) 확보에 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;card&quot;&gt;&lt;b&gt;참고 문서 활용 순서 (실무 추천)&lt;/b&gt;&lt;br /&gt;1) 카카오맵 Web API 문서로 &lt;span class=&quot;inline-code&quot;&gt;Map / Polyline / Bounds&lt;/span&gt; 사용법 확인&lt;br /&gt;2) OSRM API 문서로 &lt;span class=&quot;inline-code&quot;&gt;route&lt;/span&gt; 옵션(&lt;span class=&quot;inline-code&quot;&gt;overview&lt;/span&gt;, &lt;span class=&quot;inline-code&quot;&gt;geometries&lt;/span&gt;) 정리&lt;br /&gt;3) Geofabrik에서 OSM PBF 확보 후 자체 OSRM 구축&lt;br /&gt;4) 운영 단계에서는 OSRM GitHub 저장소로 버전 변경/이슈 확인&lt;/div&gt;
&lt;div class=&quot;callout&quot;&gt;&lt;b&gt;버전 문서 확인 팁&lt;/b&gt;&lt;br /&gt;OSRM 문서는 버전별 URL이 분리되어 있으므로, 운영 중인 OSRM 버전과 문서 버전을 맞춰 확인하는 것이 좋습니다. (예: &lt;span class=&quot;inline-code&quot;&gt;v5.24.x&lt;/span&gt; 기준 문서 사용)&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;트러블슈팅 FAQ (카카오맵 + OSRM 연동 시 자주 겪는 문제)&lt;/h2&gt;
&lt;details class=&quot;faq&quot; open=&quot;&quot;&gt;
&lt;summary&gt;경로가 바다/해외/엉뚱한 위치에 표시됩니다&lt;/summary&gt;
&lt;div class=&quot;faq-body&quot;&gt;대부분 좌표 순서 문제입니다. OSRM은 &lt;span class=&quot;inline-code&quot;&gt;[lng,lat]&lt;/span&gt;, 카카오맵 LatLng는 &lt;span class=&quot;inline-code&quot;&gt;(lat,lng)&lt;/span&gt;를 사용합니다. 매핑 시 순서를 뒤집는 로직이 누락되었는지 먼저 확인하세요.&lt;/div&gt;
&lt;/details&gt;&lt;details class=&quot;faq&quot;&gt;
&lt;summary&gt;경로를 여러 번 그리면 화면이 느려지고 잔상이 남습니다&lt;/summary&gt;
&lt;div class=&quot;faq-body&quot;&gt;이전 폴리라인/마커 정리가 누락된 경우가 많습니다. 새 경로를 그리기 전에 기존 객체에 &lt;span class=&quot;inline-code&quot;&gt;setMap(null)&lt;/span&gt;을 호출해 제거하세요. 실시간 갱신 화면일수록 이 처리가 중요합니다.&lt;/div&gt;
&lt;/details&gt;&lt;details class=&quot;faq&quot;&gt;
&lt;summary&gt;CORS 오류가 발생합니다&lt;/summary&gt;
&lt;div class=&quot;faq-body&quot;&gt;브라우저에서 OSRM 서버를 직접 호출하면 CORS 이슈가 발생할 수 있습니다. 운영 환경에서는 백엔드 프록시(BFF)를 두고, 프론트는 내부 API만 호출하는 구조가 안정적입니다.&lt;/div&gt;
&lt;/details&gt;&lt;details class=&quot;faq&quot;&gt;
&lt;summary&gt;GeoJSON과 Polyline 중 무엇부터 쓰는 게 좋을까요?&lt;/summary&gt;
&lt;div class=&quot;faq-body&quot;&gt;빠른 개발/검증이 목적이면 GeoJSON부터 시작하고, 운영 트래픽이 늘어나면 Polyline으로 전환하는 전략이 가장 효율적입니다.&lt;/div&gt;
&lt;/details&gt;&lt;details class=&quot;faq&quot;&gt;
&lt;summary&gt;퍼블릭 OSRM 서버를 운영 서비스에 써도 되나요?&lt;/summary&gt;
&lt;div class=&quot;faq-body&quot;&gt;권장하지 않습니다. 퍼블릭 서버는 테스트/데모 용도로 보는 것이 안전합니다. 실서비스는 자체 OSRM 서버 또는 관리 가능한 백엔드 프록시 구조로 운영하는 것이 좋습니다.&lt;/div&gt;
&lt;/details&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 정리는 단순한 이론 요약이 아니라, 실제로 추적관리(관제) 프로그램을 개발하면서 필요했던 기능을 구현하고 운영 관점까지 고려해 적용한 내용을 바탕으로 정리한 것입니다. 지도 UI는 카카오맵으로, 경로 연산은 OSRM으로 분리하는 구조는 비용/성능/확장성 측면에서 실무적으로 매우 현실적인 선택이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 물류, 자산 추적, 차량 관제, 현장 운영 대시보드처럼 경로 호출이 빈번한 서비스에서는 초기에 아키텍처를 잘 잡아두는 것만으로도 이후 유지보수 난이도와 운영 비용이 크게 달라집니다. 핵심은 &lt;b&gt;좌표 변환 규칙&lt;/b&gt;, &lt;b&gt;렌더링 객체 정리&lt;/b&gt;, &lt;b&gt;백엔드 프록시(BFF) + OSRM 운영 구조&lt;/b&gt;를 처음부터 명확히 설계하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저와 비슷하게 실무에서 추적관리/지도 기반 기능을 개발하고 계신 분들이라면, 이 글의 구조와 예제 코드를 출발점으로 삼아도 충분히 도움이 될 것이라고 생각합니다. 시행착오를 줄이고 빠르게 안정화하는 데 분명히 도움이 되길 바랍니다.&lt;/p&gt;
&lt;div class=&quot;callout&quot;&gt;&lt;b&gt;이 글이 특히 도움이 될 분들&lt;/b&gt;&lt;br /&gt;추적관리/관제/물류/운영 대시보드처럼 지도 위에 이동 경로를 표시해야 하는 기능을 개발 중인데, 상용 길찾기 API 비용이나 호출 제한, 운영 확장성 때문에 대안을 찾고 있는 개발자&lt;/div&gt;
&lt;div class=&quot;good&quot;&gt;&lt;b&gt;적용 전 최종 체크 포인트&lt;/b&gt;&lt;br /&gt;좌표 순서 변환 규칙, setBounds 자동 포커싱, 재렌더링 시 오버레이 정리, OSRM 자체 구축 또는 프록시 구조, GeoJSON/Polyline 선택 전략까지 정리하면 시행착오를 크게 줄일 수 있습니다.&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div class=&quot;foot&quot;&gt;
&lt;div class=&quot;kv&quot;&gt;
&lt;div&gt;추천 슬러그&lt;/div&gt;
&lt;div&gt;kakao-map-osrm-route-polyline-guide&lt;/div&gt;
&lt;div&gt;메타 설명&lt;/div&gt;
&lt;div&gt;카카오맵과 OSRM을 연동해 무비용으로 고성능 경로 탐색과 폴리라인 렌더링을 구현하는 실전 가이드. 추적관리 프로그램 실무 적용 경험을 바탕으로 좌표 변환, GeoJSON/Polyline 선택, Docker 기반 OSRM 서버 구축 및 운영 최적화까지 정리.&lt;/div&gt;
&lt;div&gt;핵심 키워드&lt;/div&gt;
&lt;div&gt;카카오맵, Kakaomap, OSRM, 경로탐색, 길찾기API, Polyline, 자바스크립트, Docker, 추적관리 프로그램, 관제 시스템&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;</description>
      <category>DEVELOPMENT</category>
      <category>KaKaoMap</category>
      <category>OSRM</category>
      <category>Polyline</category>
      <category>경로탐색</category>
      <category>관제시스템</category>
      <category>길찾기API</category>
      <category>라우팅엔진</category>
      <category>자바스크립트</category>
      <category>추적관리</category>
      <category>카카오맵</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/572</guid>
      <comments>https://odinbox.tistory.com/572#entry572comment</comments>
      <pubDate>Sun, 22 Feb 2026 01:08:37 +0900</pubDate>
    </item>
    <item>
      <title>부산에서 괌까지, 직장인의 3박 5일 꽉 찬 힐링 여행기</title>
      <link>https://odinbox.tistory.com/571</link>
      <description>&lt;div&gt;
&lt;style&gt;
    /* 오딘박스 블로그 표준 스타일 */
    .odin-container {
        font-family: 'Apple SD Gothic Neo', 'Noto Sans KR', sans-serif;
        line-height: 1.8;
        color: #333;
        font-size: 16px;
        max-width: 820px;
        margin: 0 auto;
        padding: 20px 0;
    }

    /* 제목 스타일 */
    .odin-container h2 {
        font-size: 1.4em;
        font-weight: 700;
        color: #2c3e50;
        border-bottom: 2px solid #2c3e50;
        padding-bottom: 10px;
        margin-top: 50px;
        margin-bottom: 25px;
        letter-spacing: -0.5px;
    }

    .odin-container h3 {
        font-size: 1.2em;
        font-weight: 600;
        color: #0077a3;
        margin-top: 40px;
        margin-bottom: 15px;
        border-left: 4px solid #0077a3;
        padding-left: 12px;
    }

    /* 본문 텍스트 */
    .odin-text {
        margin-bottom: 20px;
        word-break: keep-all;
        text-align: justify;
    }

    /* 강조 박스 (인용구 스타일) */
    .odin-box {
        background-color: #f8f9fa;
        border: 1px solid #e9ecef;
        padding: 20px;
        margin: 30px 0;
        border-radius: 4px;
    }

    .odin-box strong {
        color: #2c3e50;
        font-weight: 700;
    }

    /* 이미지 가이드 박스 (작성 시 참고용, 실제 이미지로 교체 필요) */
    .img-placeholder {
        background-color: #eef2f5;
        border: 2px dashed #cbd5e0;
        color: #5f6c7b;
        padding: 40px 20px;
        margin: 30px 0;
        text-align: center;
        font-size: 0.9em;
        border-radius: 8px;
    }

    .img-placeholder .guide-title {
        display: block;
        font-weight: bold;
        font-size: 1.1em;
        margin-bottom: 10px;
        color: #2d3748;
    }

    .img-placeholder .alt-text {
        display: block;
        font-size: 0.85em;
        color: #718096;
    }

    /* 리스트 스타일 */
    .odin-list {
        margin-bottom: 20px;
        padding-left: 20px;
    }

    .odin-list li {
        margin-bottom: 8px;
    }
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;odin-container&quot;&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;매일 반복되는 코드와의 씨름, 그리고 뼛속까지 시린 한국의 겨울 추위에 지쳐갈 때쯤이었습니다. 회사에서 괌으로 워크샵을 간다는 소식이 들려왔습니다. 보통 워크샵이라고 하면 짜여진 일정에 몸을 맡기는 수동적인 여행을 떠올리기 쉽지만, 이번 여행의 모토는 조금 달랐습니다. &quot;워크샵이지만 최대한 자유여행처럼.&quot; 개발자로서 효율성을 중시하는 저에게 이보다 더 매력적인 제안은 없었죠. 목요일 저녁 업무를 마치고 부산 김해공항으로 달려가 월요일 아침 바로 출근하는, 꽉 찬 3박 5일간의 기록을 풀어보려 합니다. 단순한 여행기를 넘어 2025년 현재 괌의 물가, 분위기, 그리고 놓치지 말아야 할 포인트들을 아주 상세하게 정리했습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pBHlp/dJMcagYKqxi/Hn8Nduz4bbCudgN0pAK2nK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pBHlp/dJMcagYKqxi/Hn8Nduz4bbCudgN0pAK2nK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pBHlp/dJMcagYKqxi/Hn8Nduz4bbCudgN0pAK2nK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpBHlp%2FdJMcagYKqxi%2FHn8Nduz4bbCudgN0pAK2nK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 왜 지금 괌인가? 데이터로 보는 여행 트렌드&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;여행을 떠나기 전, 습관처럼 데이터를 좀 찾아봤습니다. 2025년 말 기준으로 괌을 찾는 관광객 통계를 보니 흥미로운 점이 발견되더군요. 12월 한 달 동안 괌을 방문한 한국인이 무려 5만 명이 넘었습니다. 이는 전년 대비 65% 이상 폭증한 수치인데, 전체 괌 방문객의 절반 이상이 한국인이라는 뜻입니다.&lt;/p&gt;
&lt;div class=&quot;odin-box&quot;&gt;&lt;b&gt;Insight&lt;/b&gt;&lt;br /&gt;실제로 현지에 도착해보니 이곳이 미국령 괌인지, 한국의 거제도인지 헷갈릴 정도로 한국어 안내판과 한국인 관광객이 많았습니다. 이는 영어가 낯선 분들에게는 엄청난 심리적 안정감을 주지만, 완벽한 이국적인 고립감을 원하는 분들에게는 조금 아쉬울 수도 있는 부분입니다. 하지만 부산에서 4시간 남짓이면 도착하는 가장 가까운 미국이라는 메리트는 여전히 강력했습니다.&lt;/div&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBMUfA/dJMcagLeJ6c/RpboMLXwXsDzBv4MAMqifk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBMUfA/dJMcagLeJ6c/RpboMLXwXsDzBv4MAMqifk/img.png&quot; data-alt=&quot;부산김해공항 내부 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBMUfA/dJMcagLeJ6c/RpboMLXwXsDzBv4MAMqifk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBMUfA%2FdJMcagLeJ6c%2FRpboMLXwXsDzBv4MAMqifk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;부산김해공항 내부 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hlbun/dJMcagLeJ6b/MK4UhLKDFqRY9pMoZ00W51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hlbun/dJMcagLeJ6b/MK4UhLKDFqRY9pMoZ00W51/img.png&quot; data-alt=&quot;부산김해공항에서 먹은 음식(비빔밀면)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hlbun/dJMcagLeJ6b/MK4UhLKDFqRY9pMoZ00W51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHlbun%2FdJMcagLeJ6b%2FMK4UhLKDFqRY9pMoZ00W51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;부산김해공항에서 먹은 음식(비빔밀면)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 부산 김해공항 출발, 그리고 괌의 첫인상&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;목요일 오후 업무를 마치고 김해국제공항으로 향했습니다. 제가 이용한 항공편은 진에어 LJ921편이었습니다. 저녁 늦게 출발해 괌에는 새벽에 도착하는 일정입니다. 직장인에게 연차 소진을 최소화할 수 있는 황금 스케줄이지만, 체력적으로는 꽤 부담이 되는 것이 사실입니다. 비행시간은 약 3시간 50분. 기내식을 먹고 잠깐 눈을 붙이니 금세 착륙 안내 방송이 나왔습니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;괌 공항에 내리자마자 느껴지는 그 특유의 습하고 따뜻한 공기는 아, 정말 탈출했구나라는 해방감을 주기에 충분했습니다. 입국 심사는 생각보다 까다롭지 않았지만, 새벽 시간대라 피로가 몰려왔습니다. 숙소는 투몬 시내 한복판에 위치한 괌 플라자 리조트로 잡았습니다. 사실 괌의 호텔들은 시설 낙후 대비 가격이 비싼 편이라 가성비를 따지지 않을 수 없는데, 괌 플라자는 위치 하나만큼은 깡패 수준입니다. 렌트카 없이도 T갤러리아나 주요 쇼핑몰을 걸어서 갈 수 있다는 점이 워크샵 단체 행동에서 오는 제약을 많이 상쇄해 주었습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/becC0F/dJMcaaxtSl1/TOzG5cpBQk07pJQvbzVY0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/becC0F/dJMcaaxtSl1/TOzG5cpBQk07pJQvbzVY0k/img.png&quot; data-alt=&quot;안토니오 B. 원 팻 국제공항(Antonio B. Won Pat International Airport)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/becC0F/dJMcaaxtSl1/TOzG5cpBQk07pJQvbzVY0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbecC0F%2FdJMcaaxtSl1%2FTOzG5cpBQk07pJQvbzVY0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;안토니오 B. 원 팻 국제공항(Antonio B. Won Pat International Airport)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQRQiU/dJMcafr0cj8/ZSXM1gQeOJWi1wjHtCERz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQRQiU/dJMcafr0cj8/ZSXM1gQeOJWi1wjHtCERz1/img.png&quot; data-alt=&quot;렌트카 모습(현대 투싼)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQRQiU/dJMcafr0cj8/ZSXM1gQeOJWi1wjHtCERz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQRQiU%2FdJMcafr0cj8%2FZSXM1gQeOJWi1wjHtCERz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;렌트카 모습(현대 투싼)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmZGmy/dJMcagYKqK4/iwEpW8PZ2Jc0d3dGHWLbB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmZGmy/dJMcagYKqK4/iwEpW8PZ2Jc0d3dGHWLbB0/img.png&quot; data-alt=&quot;투몬 거리 야경모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmZGmy/dJMcagYKqK4/iwEpW8PZ2Jc0d3dGHWLbB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmZGmy%2FdJMcagYKqK4%2FiwEpW8PZ2Jc0d3dGHWLbB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;투몬 거리 야경모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 미식 탐방 : 미국적인 스케일과 섬세한 맛의 조화&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;여행의 시작은 역시 음식이죠. 렌트카를 인수하자마자 피카스 카페로 향했습니다. 이곳은 관광객뿐만 아니라 현지인들도 줄 서서 먹는 브런치 맛집입니다. 가장 유명한 메뉴인 로코모코를 주문했는데, 이게 정말 물건입니다. 보통 로코모코는 짭조름한 브라운 그레이비소스를 쓰는데, 이곳은 꾸덕꾸덕하고 고소한 크림소스를 베이스로 합니다. 밥과 패티, 그리고 반숙 계란후라이에 크림소스를 듬뿍 적셔 한 입 먹으니 비행의 피로가 싹 씻겨 내려가는 기분이었습니다. 느끼할 것 같지만 의외로 끝맛이 매콤해서 한국인 입맛에 아주 잘 맞았습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2691&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FZ5HH/dJMcabC9Mpk/jULCT9wXE7xTWnGWbEef2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FZ5HH/dJMcabC9Mpk/jULCT9wXE7xTWnGWbEef2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FZ5HH/dJMcabC9Mpk/jULCT9wXE7xTWnGWbEef2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFZ5HH%2FdJMcabC9Mpk%2FjULCT9wXE7xTWnGWbEef2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2691&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2691&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBgcgY/dJMcai93V3l/LZ8OCh0R82jtgbN3k0J7f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBgcgY/dJMcai93V3l/LZ8OCh0R82jtgbN3k0J7f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBgcgY/dJMcai93V3l/LZ8OCh0R82jtgbN3k0J7f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBgcgY%2FdJMcai93V3l%2FLZ8OCh0R82jtgbN3k0J7f1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdcV9U/dJMcafle9dC/FQrrhOJ2RToJ3CgTt1Sl7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdcV9U/dJMcafle9dC/FQrrhOJ2RToJ3CgTt1Sl7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdcV9U/dJMcafle9dC/FQrrhOJ2RToJ3CgTt1Sl7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdcV9U%2FdJMcafle9dC%2FFQrrhOJ2RToJ3CgTt1Sl7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GvffZ/dJMcafle9dD/PqLSHbpvWkMMZbSfHAV1v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GvffZ/dJMcafle9dD/PqLSHbpvWkMMZbSfHAV1v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GvffZ/dJMcafle9dD/PqLSHbpvWkMMZbSfHAV1v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGvffZ%2FdJMcafle9dD%2FPqLSHbpvWkMMZbSfHAV1v1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b29Ihb/dJMcah4q0Sp/8lKntoEKgBlzCSU473kOT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b29Ihb/dJMcah4q0Sp/8lKntoEKgBlzCSU473kOT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b29Ihb/dJMcah4q0Sp/8lKntoEKgBlzCSU473kOT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb29Ihb%2FdJMcah4q0Sp%2F8lKntoEKgBlzCSU473kOT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;압도적인 양(Portion)의 충격과 쇼핑모습&lt;/h3&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ggdm0/dJMcagqUD5U/wkyLwYn7fi19jIdmSHDKJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ggdm0/dJMcagqUD5U/wkyLwYn7fi19jIdmSHDKJk/img.png&quot; style=&quot;width: 32.5203%; margin-right: 10px;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ggdm0/dJMcagqUD5U/wkyLwYn7fi19jIdmSHDKJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGgdm0%2FdJMcagqUD5U%2FwkyLwYn7fi19jIdmSHDKJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yBlYN/dJMcabb3UQx/FMShNW0BOWvTwRCnoKESC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yBlYN/dJMcabb3UQx/FMShNW0BOWvTwRCnoKESC0/img.png&quot; style=&quot;width: 32.5203%; margin-right: 10px;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yBlYN/dJMcabb3UQx/FMShNW0BOWvTwRCnoKESC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyBlYN%2FdJMcabb3UQx%2FFMShNW0BOWvTwRCnoKESC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnhL1F/dJMcafr0cto/ILzDSgbRacKzbJBCKKZ4ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnhL1F/dJMcafr0cto/ILzDSgbRacKzbJBCKKZ4ak/img.png&quot; style=&quot;width: 32.5203%;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnhL1F/dJMcafr0cto/ILzDSgbRacKzbJBCKKZ4ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnhL1F%2FdJMcafr0cto%2FILzDSgbRacKzbJBCKKZ4ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;케이마트(KMART) 외부모습과 내부모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsIDfv/dJMcahQTBcJ/iwBG1K8tv4sTpkFJDALPV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsIDfv/dJMcahQTBcJ/iwBG1K8tv4sTpkFJDALPV1/img.png&quot; style=&quot;width: 23.7746%; margin-right: 10px;&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;24.07&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsIDfv/dJMcahQTBcJ/iwBG1K8tv4sTpkFJDALPV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsIDfv%2FdJMcahQTBcJ%2FiwBG1K8tv4sTpkFJDALPV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QHkm3/dJMcahJ9n9R/L6hRSgLZ2VjOmNGDgdXUc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QHkm3/dJMcahJ9n9R/L6hRSgLZ2VjOmNGDgdXUc0/img.png&quot; style=&quot;width: 75.0059%;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;75.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QHkm3/dJMcahJ9n9R/L6hRSgLZ2VjOmNGDgdXUc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQHkm3%2FdJMcahJ9n9R%2FL6hRSgLZ2VjOmNGDgdXUc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;GPO 아울렛 야경 및 GPO 근처에 있는 로스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3sAxW/dJMcahJ9n9S/D0ET8D7rM4q1dan7xQumLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3sAxW/dJMcahJ9n9S/D0ET8D7rM4q1dan7xQumLK/img.png&quot; style=&quot;width: 49.3902%; margin-right: 10px;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3sAxW/dJMcahJ9n9S/D0ET8D7rM4q1dan7xQumLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3sAxW%2FdJMcahJ9n9S%2FD0ET8D7rM4q1dan7xQumLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNN7CX/dJMcajgO83B/Nq5yNc0syc2tRkh3kchqT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNN7CX/dJMcajgO83B/Nq5yNc0syc2tRkh3kchqT0/img.png&quot; style=&quot;width: 49.3902%;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNN7CX/dJMcajgO83B/Nq5yNc0syc2tRkh3kchqT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNN7CX%2FdJMcajgO83B%2FNq5yNc0syc2tRkh3kchqT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;일본라멘가게 외부모습과 일본라멘 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ExKwD/dJMcahQTBcQ/ckI0SAl2Hc51DquJZc4VOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ExKwD/dJMcahQTBcQ/ckI0SAl2Hc51DquJZc4VOK/img.png&quot; style=&quot;width: 42.1072%; margin-right: 10px;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;43.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ExKwD/dJMcahQTBcQ/ckI0SAl2Hc51DquJZc4VOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FExKwD%2FdJMcahQTBcQ%2FckI0SAl2Hc51DquJZc4VOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MJdBV/dJMcajgO83A/iQ3YfNlKCh3PgtK8k3bj00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MJdBV/dJMcajgO83A/iQ3YfNlKCh3PgtK8k3bj00/img.png&quot; style=&quot;width: 13.3467%; margin-right: 10px;&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;13.68&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MJdBV/dJMcajgO83A/iQ3YfNlKCh3PgtK8k3bj00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMJdBV%2FdJMcajgO83A%2FiQ3YfNlKCh3PgtK8k3bj00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LhitR/dJMcahJ9n9T/QGrmk3VA5nGu1zcJRm0Wok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LhitR/dJMcahJ9n9T/QGrmk3VA5nGu1zcJRm0Wok/img.png&quot; style=&quot;width: 42.1072%;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;43.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LhitR/dJMcahJ9n9T/QGrmk3VA5nGu1zcJRm0Wok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLhitR%2FdJMcahJ9n9T%2FQGrmk3VA5nGu1zcJRm0Wok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;하가나쇼핑센터에 있는 로쓰 야경 및 문닫기 전이라 어수선하다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nTbkA/dJMcagqUD5Z/kajTS9xIisnfhLkg0w9FA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nTbkA/dJMcagqUD5Z/kajTS9xIisnfhLkg0w9FA0/img.png&quot; style=&quot;width: 75.0059%; margin-right: 10px;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;75.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nTbkA/dJMcagqUD5Z/kajTS9xIisnfhLkg0w9FA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnTbkA%2FdJMcagqUD5Z%2FkajTS9xIisnfhLkg0w9FA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/909H6/dJMcafr0ctp/4lRjlVKLRTrIOzL2KJxog0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/909H6/dJMcafr0ctp/4lRjlVKLRTrIOzL2KJxog0/img.png&quot; style=&quot;width: 23.7746%;&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;24.07&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/909H6/dJMcafr0ctp/4lRjlVKLRTrIOzL2KJxog0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F909H6%2FdJMcafr0ctp%2F4lRjlVKLRTrIOzL2KJxog0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;마트 안 모습 전부 너무 크다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k1afh/dJMcaaRNGkr/sVPMkdCaSiXkYsYgoiBozK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k1afh/dJMcaaRNGkr/sVPMkdCaSiXkYsYgoiBozK/img.png&quot; style=&quot;width: 23.7746%; margin-right: 10px;&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;24.07&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k1afh/dJMcaaRNGkr/sVPMkdCaSiXkYsYgoiBozK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk1afh%2FdJMcaaRNGkr%2FsVPMkdCaSiXkYsYgoiBozK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dV72aa/dJMcahQTDsQ/onKpGpHrPLghd1FQRe1Ks0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dV72aa/dJMcahQTDsQ/onKpGpHrPLghd1FQRe1Ks0/img.png&quot; style=&quot;width: 75.0059%;&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;75.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dV72aa/dJMcahQTDsQ/onKpGpHrPLghd1FQRe1Ks0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdV72aa%2FdJMcahQTDsQ%2FonKpGpHrPLghd1FQRe1Ks0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;마이크로네시아몰, 빨간버스가 셔틀버스같이 괌의 애지간한곳을 다 가는거같다.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;저녁에는 괌의 음식 양에 압도당했습니다. 후지 이찌방 라멘이나 K마트 푸드코트에서 음식을 시켜보면 알게 됩니다. 이걸 혼자 다 먹으라고?라는 말이 절로 나올 정도로 양이 많습니다. 미국의 풍요로움이 식탁 위에 그대로 반영된 느낌이랄까요. 가성비를 따진다면 괌에서의 식사는 꽤 만족스러운 편입니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;그리고 쇼핑을 통해 다양한 것도 많이 구경을 할 수 있었습니다. 역시 미국답게 모든 물건 용량이 한국과 비교하면 엄청 많이 있었습니다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 쇼핑의 새로운 강자, 빌리지 오브 돈키&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;2024년에 오픈했다는 빌리지 오브 돈키(돈키호테)는 이번 여행에서 가장 인상 깊은 장소 중 하나였습니다. 일본 여행을 가면 좁은 통로의 돈키호테를 생각하기 마련인데, 괌의 돈키호테는 다릅니다. 미국의 거대한 창고형 마트 스타일에 일본의 디테일한 상품 구성을 섞어놓았습니다. 식료품부터 의약품, 기념품까지 없는 게 없는데, 무엇보다 24시간(혹은 새벽 1시까지) 운영한다는 점이 최고였습니다. 꽉 찬 낮 일정을 보내고 밤에 잠이 안 올 때 슬리퍼 끌고 쇼핑하러 가기에 이만한 곳이 없습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdzjV0/dJMcahchrPa/eUJ0YKrVkKu6K4qEregXlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdzjV0/dJMcahchrPa/eUJ0YKrVkKu6K4qEregXlk/img.png&quot; data-alt=&quot;빌리지 오브 돈키 외부전경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdzjV0/dJMcahchrPa/eUJ0YKrVkKu6K4qEregXlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdzjV0%2FdJMcahchrPa%2FeUJ0YKrVkKu6K4qEregXlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;빌리지 오브 돈키 외부전경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CLFP2/dJMcaf6BYOW/CwD2rJDMgZ06BdSnvfI7E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CLFP2/dJMcaf6BYOW/CwD2rJDMgZ06BdSnvfI7E0/img.png&quot; data-alt=&quot;빌리지 오브 돈키 내부 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CLFP2/dJMcaf6BYOW/CwD2rJDMgZ06BdSnvfI7E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCLFP2%2FdJMcaf6BYOW%2FCwD2rJDMgZ06BdSnvfI7E0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;빌리지 오브 돈키 내부 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 괌의 바다, 그리고 날씨라는 변수, 스테이크&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;둘째 날은 이파오 비치로 향했습니다. 사람들이 북적거리는 투몬 비치보다 훨씬 한적하고 물이 맑았습니다. 스노클링 장비를 챙겨서 물에 들어가니 형형색색의 물고기들이 발치에서 헤엄치는 게 보였습니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;하지만 괌 여행에서 날씨는 정말 예측할 수 없는 변수입니다. 셋째 날 돌핀 크루즈를 예약해 두었는데, 아침부터 비가 쏟아졌습니다. 배를 타고 나가는 일정은 파도가 높으면 멀미로 고생만 하고 돌고래는 구경도 못 할 확률이 높습니다. 과감하게 일정을 취소하고 대안을 찾았습니다. 비가 올 때는 무리한 야외 활동보다는 쇼핑몰 투어나 맛집 탐방으로 빠르게 태세를 전환하는 유연함이 필요합니다. 날이 조금 개었을 때 에메랄드 밸리를 찾았는데, 물뱀이 지나가는 것도 보일 정도로 투명한 물빛이 인상적이었습니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;돌핀투어는 살짝 아쉽다고 느낀 것은 타기 전에 찾아본 결과로는 참치회나 이런것도 괜찮아보였는데 실제로 봣을 때 사실 그렇게 좋지 않았습니다. 양도 적었고 어떻게든 작은 배에 많은 사람들을 타게 해야 이익을 남기는 구조일거라 어떻게든 자리를 꽉 채우는 모습이였습니다. 낚시나 물놀이를 일부 할 수 있으나 시간이 그렇게 길지 않으니 냉정하게 물놀이 이런것을 좋아한다면 그냥 그 시간에 해변가서 개인적으로 하시는게 더 좋습니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 돌핀투어를 마치고 숙소에서 샤워하고 옷을 갈아입은 뒤 롱혼스테이크를 먹으러 갔습니다. GPO 근처에 있다고 들어 출발을 했고 그 근처에 애플비즈?라는 곳도 괜찮다고 했는데 롱혼스테이크에서 한번 먹어보려고 했습니다. 저의 경우 립아이를 시켰고 한국에서 먹었던 것보다 더 맛있다고 느껴졌습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bklC7G/dJMcabwmF1a/t4VK12EuBIGj1kxr0Nz2Xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bklC7G/dJMcabwmF1a/t4VK12EuBIGj1kxr0Nz2Xk/img.png&quot; data-alt=&quot;아이러브이파오 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bklC7G/dJMcabwmF1a/t4VK12EuBIGj1kxr0Nz2Xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbklC7G%2FdJMcabwmF1a%2Ft4VK12EuBIGj1kxr0Nz2Xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아이러브이파오 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zkFEB/dJMcabwmF1b/F8K37lRG6pzPoMvHyhnvi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zkFEB/dJMcabwmF1b/F8K37lRG6pzPoMvHyhnvi0/img.png&quot; data-alt=&quot;이파오해변에 있는 아이러브괌&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zkFEB/dJMcabwmF1b/F8K37lRG6pzPoMvHyhnvi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzkFEB%2FdJMcabwmF1b%2FF8K37lRG6pzPoMvHyhnvi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이파오해변에 있는 아이러브괌&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mRSYf/dJMcabwmF1c/RQdLAORq84T7K2MpsUTBS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mRSYf/dJMcabwmF1c/RQdLAORq84T7K2MpsUTBS1/img.png&quot; data-alt=&quot;이파오해변 전경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mRSYf/dJMcabwmF1c/RQdLAORq84T7K2MpsUTBS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmRSYf%2FdJMcabwmF1c%2FRQdLAORq84T7K2MpsUTBS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이파오해변 전경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NSTAH/dJMcaaqHXOV/4fMXKdqCOvGIforeQwyXl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NSTAH/dJMcaaqHXOV/4fMXKdqCOvGIforeQwyXl0/img.png&quot; data-alt=&quot;이파오비치 전경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NSTAH/dJMcaaqHXOV/4fMXKdqCOvGIforeQwyXl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNSTAH%2FdJMcaaqHXOV%2F4fMXKdqCOvGIforeQwyXl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이파오비치 전경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuVuuA/dJMcaaqHXOW/uSbUCv0ku0wzwxo8sA6exK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuVuuA/dJMcaaqHXOW/uSbUCv0ku0wzwxo8sA6exK/img.png&quot; data-alt=&quot;이파오해변에서 먹늰 BBQ 준비모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuVuuA/dJMcaaqHXOW/uSbUCv0ku0wzwxo8sA6exK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuVuuA%2FdJMcaaqHXOW%2FuSbUCv0ku0wzwxo8sA6exK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이파오해변에서 먹늰 BBQ 준비모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CiRht/dJMcafr0cHS/fiFAJC72Vl2uhKzh47tjm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CiRht/dJMcafr0cHS/fiFAJC72Vl2uhKzh47tjm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CiRht/dJMcafr0cHS/fiFAJC72Vl2uhKzh47tjm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCiRht%2FdJMcafr0cHS%2FfiFAJC72Vl2uhKzh47tjm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sGXm8/dJMcaaqHXOU/KCueNMFgku7rKSvyUbAuok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sGXm8/dJMcaaqHXOU/KCueNMFgku7rKSvyUbAuok/img.png&quot; data-alt=&quot;이파오해변 물색상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sGXm8/dJMcaaqHXOU/KCueNMFgku7rKSvyUbAuok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsGXm8%2FdJMcaaqHXOU%2FKCueNMFgku7rKSvyUbAuok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이파오해변 물색상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckrfiu/dJMcabb3U71/JwwsTZIiofL5UUSmrLAgFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckrfiu/dJMcabb3U71/JwwsTZIiofL5UUSmrLAgFK/img.png&quot; data-alt=&quot;이파오해변 길 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckrfiu/dJMcabb3U71/JwwsTZIiofL5UUSmrLAgFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fckrfiu%2FdJMcabb3U71%2FJwwsTZIiofL5UUSmrLAgFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이파오해변 길 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sfQ6e/dJMcacWkYlg/CiACkTLBo7wg1oMSlVlDY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sfQ6e/dJMcacWkYlg/CiACkTLBo7wg1oMSlVlDY0/img.png&quot; data-alt=&quot;에메랄드밸리 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sfQ6e/dJMcacWkYlg/CiACkTLBo7wg1oMSlVlDY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsfQ6e%2FdJMcacWkYlg%2FCiACkTLBo7wg1oMSlVlDY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;에메랄드밸리 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bExNgt/dJMcabb3U7W/8G93Ch3upoeXgBY7MtFI5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bExNgt/dJMcabb3U7W/8G93Ch3upoeXgBY7MtFI5k/img.png&quot; data-alt=&quot;에메랄드 밸리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bExNgt/dJMcabb3U7W/8G93Ch3upoeXgBY7MtFI5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbExNgt%2FdJMcabb3U7W%2F8G93Ch3upoeXgBY7MtFI5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;에메랄드 밸리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIMtjK/dJMcabb3U7Y/tESwmr1YMENATRnpYeNeGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIMtjK/dJMcabb3U7Y/tESwmr1YMENATRnpYeNeGK/img.png&quot; data-alt=&quot;에메랄드 밸리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIMtjK/dJMcabb3U7Y/tESwmr1YMENATRnpYeNeGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIMtjK%2FdJMcabb3U7Y%2FtESwmr1YMENATRnpYeNeGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;에메랄드 밸리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqtqGh/dJMcag5xnu9/AqxZ5kk4QNapDKzE5L8a4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqtqGh/dJMcag5xnu9/AqxZ5kk4QNapDKzE5L8a4k/img.png&quot; data-alt=&quot;돌핀투어 선착장 근처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqtqGh/dJMcag5xnu9/AqxZ5kk4QNapDKzE5L8a4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqtqGh%2FdJMcag5xnu9%2FAqxZ5kk4QNapDKzE5L8a4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;돌핀투어 선착장 근처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ercKuS/dJMcahwB44T/8Y2et5yGyQxmDQ1wHeEcs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ercKuS/dJMcahwB44T/8Y2et5yGyQxmDQ1wHeEcs1/img.png&quot; data-alt=&quot;돌핀투어 선착장&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ercKuS/dJMcahwB44T/8Y2et5yGyQxmDQ1wHeEcs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FercKuS%2FdJMcahwB44T%2F8Y2et5yGyQxmDQ1wHeEcs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;돌핀투어 선착장&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfGIgg/dJMcag5xnva/evyI9lGk8yVkLKVDDDgI5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfGIgg/dJMcag5xnva/evyI9lGk8yVkLKVDDDgI5k/img.png&quot; data-alt=&quot;돌핀투어 선착장 같이 나가는 배 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfGIgg/dJMcag5xnva/evyI9lGk8yVkLKVDDDgI5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfGIgg%2FdJMcag5xnva%2FevyI9lGk8yVkLKVDDDgI5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;2250&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;돌핀투어 선착장 같이 나가는 배 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IS1g7/dJMcai93Wrr/YzmvvkmcSsMhEpK4HGuPBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IS1g7/dJMcai93Wrr/YzmvvkmcSsMhEpK4HGuPBK/img.png&quot; data-alt=&quot;돌핀투어 바닷가 근처모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IS1g7/dJMcai93Wrr/YzmvvkmcSsMhEpK4HGuPBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIS1g7%2FdJMcai93Wrr%2FYzmvvkmcSsMhEpK4HGuPBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;돌핀투어 바닷가 근처모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/spEVd/dJMcaibdxyi/hCVxwxC5H2JiIJ60aidylk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/spEVd/dJMcaibdxyi/hCVxwxC5H2JiIJ60aidylk/img.png&quot; data-alt=&quot;롱혼스테이크 앞 거리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/spEVd/dJMcaibdxyi/hCVxwxC5H2JiIJ60aidylk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FspEVd%2FdJMcaibdxyi%2FhCVxwxC5H2JiIJ60aidylk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;롱혼스테이크 앞 거리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8vWi1/dJMcaibdxyj/5FT3vHkS3tnmjbe1Cldcm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8vWi1/dJMcaibdxyj/5FT3vHkS3tnmjbe1Cldcm0/img.png&quot; data-alt=&quot;롱혼스테이크 가게 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8vWi1/dJMcaibdxyj/5FT3vHkS3tnmjbe1Cldcm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8vWi1%2FdJMcaibdxyj%2F5FT3vHkS3tnmjbe1Cldcm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;롱혼스테이크 가게 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yHX1n/dJMcahi5Bmm/xKpT8hOHcBEca4khFwmO1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yHX1n/dJMcahi5Bmm/xKpT8hOHcBEca4khFwmO1K/img.png&quot; data-alt=&quot;롱혼스테이크 메뉴판&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yHX1n/dJMcahi5Bmm/xKpT8hOHcBEca4khFwmO1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyHX1n%2FdJMcahi5Bmm%2FxKpT8hOHcBEca4khFwmO1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;롱혼스테이크 메뉴판&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxuaMp/dJMcagRZ4Zv/Uq5C2ez8DhtBfKmNjdsROk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxuaMp/dJMcagRZ4Zv/Uq5C2ez8DhtBfKmNjdsROk/img.png&quot; data-alt=&quot;롱혼스테이크 립아이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxuaMp/dJMcagRZ4Zv/Uq5C2ez8DhtBfKmNjdsROk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxuaMp%2FdJMcagRZ4Zv%2FUq5C2ez8DhtBfKmNjdsROk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;롱혼스테이크 립아이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/68sG2/dJMcahi5Bmo/KSDkLdJhCfRIZzoLnykyP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/68sG2/dJMcahi5Bmo/KSDkLdJhCfRIZzoLnykyP1/img.png&quot; data-alt=&quot;롱혼스테이크 스테이크 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/68sG2/dJMcahi5Bmo/KSDkLdJhCfRIZzoLnykyP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F68sG2%2FdJMcahi5Bmo%2FKSDkLdJhCfRIZzoLnykyP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;롱혼스테이크 스테이크 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KqUY5/dJMcaaEfOcJ/GEUZ2vQko4t8HjkXfnqum0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KqUY5/dJMcaaEfOcJ/GEUZ2vQko4t8HjkXfnqum0/img.png&quot; data-alt=&quot;GPO 안에 있는 카페 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KqUY5/dJMcaaEfOcJ/GEUZ2vQko4t8HjkXfnqum0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKqUY5%2FdJMcaaEfOcJ%2FGEUZ2vQko4t8HjkXfnqum0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPO 안에 있는 카페 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zRRnu/dJMcaibdxyk/wLLk5TpdMC9AGFHfqLV4C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zRRnu/dJMcaibdxyk/wLLk5TpdMC9AGFHfqLV4C1/img.png&quot; data-alt=&quot;GPO 안에 있는 카페에서 시킨 아메리카노와 건강주스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zRRnu/dJMcaibdxyk/wLLk5TpdMC9AGFHfqLV4C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzRRnu%2FdJMcaibdxyk%2FwLLk5TpdMC9AGFHfqLV4C1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPO 안에 있는 카페에서 시킨 아메리카노와 건강주스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgVjdf/dJMcaibdxyh/tufDOJAJnShyQ6Dsb3Ew4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgVjdf/dJMcaibdxyh/tufDOJAJnShyQ6Dsb3Ew4k/img.png&quot; data-alt=&quot;GPO 안 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgVjdf/dJMcaibdxyh/tufDOJAJnShyQ6Dsb3Ew4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgVjdf%2FdJMcaibdxyh%2FtufDOJAJnShyQ6Dsb3Ew4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPO 안 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tkf9s/dJMcahi5Bmn/CL8MwV9WDxMMIyauHv9PMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tkf9s/dJMcahi5Bmn/CL8MwV9WDxMMIyauHv9PMk/img.png&quot; data-alt=&quot;GPO 앞 도로 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tkf9s/dJMcahi5Bmn/CL8MwV9WDxMMIyauHv9PMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTkf9s%2FdJMcahi5Bmn%2FCL8MwV9WDxMMIyauHv9PMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPO 앞 도로 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/da7M6C/dJMcaaEfOcI/1krfpmcyAUjMt2dPtdPlt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/da7M6C/dJMcaaEfOcI/1krfpmcyAUjMt2dPtdPlt0/img.png&quot; data-alt=&quot;괌에서 운전하는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/da7M6C/dJMcaaEfOcI/1krfpmcyAUjMt2dPtdPlt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fda7M6C%2FdJMcaaEfOcI%2F1krfpmcyAUjMt2dPtdPlt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;괌에서 운전하는 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 럭셔리 다이닝의 정점, 츠바키 타워 뷔페&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;이번 워크샵의 하이라이트는 단연 더 츠바키 타워의 카사 오세아노 뷔페였습니다. 괌에서 가장 비싼 호텔 뷔페답게 입장부터 분위기가 달랐습니다. 해산물 코너에는 신선한 사시미와 스시가 가득했고, 그릴 코너의 스테이크는 굽기가 완벽했습니다. 맥주와 와인이 무제한으로 제공된다는 점도 애주가들에게는 천국 같은 소식이죠. 식사를 하다 보면 창밖으로 분수 쇼가 펼쳐지는데, 라스베이거스만큼 웅장하진 않아도 괌의 밤하늘과 어우러져 꽤 로맨틱한 분위기를 연출합니다. 1인당 가격이 만만치 않지만, 여행 중 한 번쯤은 이런 호사를 누려보는 것도 나쁘지 않다는 생각이 들었습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nQ43S/dJMcacWkYLi/XcdxCFNtkZ1LqkkJLUCoA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nQ43S/dJMcacWkYLi/XcdxCFNtkZ1LqkkJLUCoA0/img.png&quot; data-alt=&quot;입구에 있던 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nQ43S/dJMcacWkYLi/XcdxCFNtkZ1LqkkJLUCoA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnQ43S%2FdJMcacWkYLi%2FXcdxCFNtkZ1LqkkJLUCoA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;입구에 있던 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUpPOr/dJMcacWkYLh/0VfYUiokv2wQTBhUnlgMP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUpPOr/dJMcacWkYLh/0VfYUiokv2wQTBhUnlgMP1/img.png&quot; data-alt=&quot;뷔폐 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUpPOr/dJMcacWkYLh/0VfYUiokv2wQTBhUnlgMP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUpPOr%2FdJMcacWkYLh%2F0VfYUiokv2wQTBhUnlgMP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뷔폐 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUgd3x/dJMcaiCfb53/Bhwolkd16DPf9awAeqoJUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUgd3x/dJMcaiCfb53/Bhwolkd16DPf9awAeqoJUK/img.png&quot; data-alt=&quot;뷔폐 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUgd3x/dJMcaiCfb53/Bhwolkd16DPf9awAeqoJUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUgd3x%2FdJMcaiCfb53%2FBhwolkd16DPf9awAeqoJUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뷔폐 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cu5XUH/dJMcaiCfb52/MjRX4zw2OFtQErJgLdRblk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cu5XUH/dJMcaiCfb52/MjRX4zw2OFtQErJgLdRblk/img.png&quot; data-alt=&quot;뷔폐 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cu5XUH/dJMcaiCfb52/MjRX4zw2OFtQErJgLdRblk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcu5XUH%2FdJMcaiCfb52%2FMjRX4zw2OFtQErJgLdRblk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뷔폐 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7rnuF/dJMcaiCfb51/CibyvpjZD4xQBgvsHwmaV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7rnuF/dJMcaiCfb51/CibyvpjZD4xQBgvsHwmaV0/img.png&quot; data-alt=&quot;뷔폐에서 밖을 바라본 야경모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7rnuF/dJMcaiCfb51/CibyvpjZD4xQBgvsHwmaV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7rnuF%2FdJMcaiCfb51%2FCibyvpjZD4xQBgvsHwmaV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뷔폐에서 밖을 바라본 야경모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q07ql/dJMcacWkYLj/vGhzatMYcvs5ddEWl9FLJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q07ql/dJMcacWkYLj/vGhzatMYcvs5ddEWl9FLJk/img.png&quot; data-alt=&quot;분수쇼 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q07ql/dJMcacWkYLj/vGhzatMYcvs5ddEWl9FLJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ07ql%2FdJMcacWkYLj%2FvGhzatMYcvs5ddEWl9FLJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;분수쇼 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 남부 투어와 역사적 의미, 그리고 주유소 이용 팁&lt;/h2&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;마지막 날 아침에는 바로 차를 쓸 수 없기도 했고 주위를 둘러 보기로 했습니다. 괌 프라자 근처에 재팬스토어도 있었고 아침에 조식 대신 다른 것을 먹자라는 생각으로 근처에 브런치 먹을 곳을 찾아보니 더 크랙드 에그 (The kracked egg)로 가보기로 했습니다. 이때 저는 치즈버거를 먹었는데 머스타드소스가 정말 맛있었습니다. 한국에서 흔히 먹던 머스타드 소스와는 다른 맛이였습니다. 그렇게 다시 숙소로 돌아가면서 카페에 들러 커피한잔을 했습니다. 밀크티 같은 느낌으로 맛있습니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;렌트카를 타고 남부로 드라이브를 떠났습니다. 괌의 도로는 운전하기 편하지만, 주유소 이용 방식은 한국과 달라 당황할 수 있습니다. 괌의 쉘(Shell) 주유소는 대부분 셀프인데, 한국처럼 기계에서 바로 결제하는 게 아닙니다. 먼저 주유기 앞에 차를 대고 주유기를 든 다음, 편의점 안으로 들어가 직원에게 3번 주유기, 레귤러 가득(Number 3, Regular Full)이라고 말하고 결제를 해야 기름이 나옵니다. 처음엔 어색했지만 몇 번 해보니 이 아날로그적인 방식도 꽤 재미있더군요.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;사랑의 절벽에도 들렀습니다. 탁 트인 바다 전망도 좋았지만, 개인적으로 더 기억에 남는 건 그곳에 있는 9/11 평화 기념비였습니다. 세계 무역 센터를 상징하는 두 기둥을 괌의 전통 가옥 양식인 라떼 스톤이 받치고 있는 형상인데, 괌이 지리적으로는 멀리 떨어져 있어도 엄연한 미국의 영토이며 그 아픔을 함께하고 있다는 연대감을 느낄 수 있었습니다. 그리고 바로 근처에 위치하고 있는 건비치를 가게 되었는데 이파오와 다른 느낌으로 조용하고 야경이 정말 이뻤습니다. 그리고 공항이 바로 근처이다보니 비행기가 왔다갔다 하는 모습과 함께 정말 이쁜 모습이였습니다.&lt;/p&gt;
&lt;div class=&quot;img-placeholder&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HVHNl/dJMcabiROOE/25fZmDbzdcfmOARwbeer5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HVHNl/dJMcabiROOE/25fZmDbzdcfmOARwbeer5k/img.png&quot; data-alt=&quot;브런치 먹으러가는 카페 길거리 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HVHNl/dJMcabiROOE/25fZmDbzdcfmOARwbeer5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHVHNl%2FdJMcabiROOE%2F25fZmDbzdcfmOARwbeer5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브런치 먹으러가는 카페 길거리 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TWcjn/dJMcagYKrNC/qWyTzVa8zXr2IT9CKM1I51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TWcjn/dJMcagYKrNC/qWyTzVa8zXr2IT9CKM1I51/img.png&quot; data-alt=&quot;가는 길에 건물이 이뻐서 찍었다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TWcjn/dJMcagYKrNC/qWyTzVa8zXr2IT9CKM1I51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTWcjn%2FdJMcagYKrNC%2FqWyTzVa8zXr2IT9CKM1I51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;가는 길에 건물이 이뻐서 찍었다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cddzBd/dJMcadHGvr5/sFunUK1GzGI1ZgPIariDy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cddzBd/dJMcadHGvr5/sFunUK1GzGI1ZgPIariDy0/img.png&quot; data-alt=&quot;더 크랙드 에그 매장 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cddzBd/dJMcadHGvr5/sFunUK1GzGI1ZgPIariDy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcddzBd%2FdJMcadHGvr5%2FsFunUK1GzGI1ZgPIariDy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;더 크랙드 에그 매장 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k3pmR/dJMcagYKrNB/eqEHsI8pUBQlkTFSAwB94k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k3pmR/dJMcagYKrNB/eqEHsI8pUBQlkTFSAwB94k/img.png&quot; data-alt=&quot;매장 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k3pmR/dJMcagYKrNB/eqEHsI8pUBQlkTFSAwB94k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk3pmR%2FdJMcagYKrNB%2FeqEHsI8pUBQlkTFSAwB94k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;매장 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JD8VE/dJMcajgPae2/cNhSkBA8IIzAqRXEy2rR5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JD8VE/dJMcajgPae2/cNhSkBA8IIzAqRXEy2rR5k/img.png&quot; data-alt=&quot;치즈버거 세트 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JD8VE/dJMcajgPae2/cNhSkBA8IIzAqRXEy2rR5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJD8VE%2FdJMcajgPae2%2FcNhSkBA8IIzAqRXEy2rR5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;치즈버거 세트 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3VogP/dJMcacB3K8c/1dcKlxpvg70NsgpUKJCus1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3VogP/dJMcacB3K8c/1dcKlxpvg70NsgpUKJCus1/img.png&quot; data-alt=&quot;치즈버거 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3VogP/dJMcacB3K8c/1dcKlxpvg70NsgpUKJCus1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3VogP%2FdJMcacB3K8c%2F1dcKlxpvg70NsgpUKJCus1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;치즈버거 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAnzld/dJMcaaRNGrr/IGw83kGwiVPpIerbOgM5Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAnzld/dJMcaaRNGrr/IGw83kGwiVPpIerbOgM5Sk/img.png&quot; data-alt=&quot;돌아가는 길에 본 카페에 바로 들어가본다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAnzld/dJMcaaRNGrr/IGw83kGwiVPpIerbOgM5Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAnzld%2FdJMcaaRNGrr%2FIGw83kGwiVPpIerbOgM5Sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;돌아가는 길에 본 카페에 바로 들어가본다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYNJ2m/dJMcag5xpFg/Q7Z7k6Uq8cXPp94LONk0jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYNJ2m/dJMcag5xpFg/Q7Z7k6Uq8cXPp94LONk0jk/img.png&quot; data-alt=&quot;우유와 아메리카노 이렇게 섞인거였는데 맛있었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYNJ2m/dJMcag5xpFg/Q7Z7k6Uq8cXPp94LONk0jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYNJ2m%2FdJMcag5xpFg%2FQ7Z7k6Uq8cXPp94LONk0jk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;우유와 아메리카노 이렇게 섞인거였는데 맛있었다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSkzXH/dJMcadHGvaV/GWDlvU8wECJMCQQu78lt1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSkzXH/dJMcadHGvaV/GWDlvU8wECJMCQQu78lt1k/img.png&quot; data-alt=&quot;주유하는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSkzXH/dJMcadHGvaV/GWDlvU8wECJMCQQu78lt1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSkzXH%2FdJMcadHGvaV%2FGWDlvU8wECJMCQQu78lt1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주유하는 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rtUT9/dJMcagYKrt8/NnlHxAKRhJ317x6Ufswq7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rtUT9/dJMcagYKrt8/NnlHxAKRhJ317x6Ufswq7k/img.png&quot; data-alt=&quot;주유소 마트 모습, 우리로 치면 그냥 흔한 편의점 느낌인듯&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rtUT9/dJMcagYKrt8/NnlHxAKRhJ317x6Ufswq7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrtUT9%2FdJMcagYKrt8%2FNnlHxAKRhJ317x6Ufswq7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주유소 마트 모습, 우리로 치면 그냥 흔한 편의점 느낌인듯&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwyyLr/dJMcahchsiV/aYM8tar3PhHwqm8Uv80n00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwyyLr/dJMcahchsiV/aYM8tar3PhHwqm8Uv80n00/img.png&quot; data-alt=&quot;GPO 주유소 근처에서 찍은 무지개 이쁘다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwyyLr/dJMcahchsiV/aYM8tar3PhHwqm8Uv80n00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwyyLr%2FdJMcahchsiV%2FaYM8tar3PhHwqm8Uv80n00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPO 주유소 근처에서 찍은 무지개 이쁘다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/43BVx/dJMcadHGvaU/NgNTAsyKz0HDBhf0rSBByK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/43BVx/dJMcadHGvaU/NgNTAsyKz0HDBhf0rSBByK/img.png&quot; data-alt=&quot;피쉬아이수중전망대 못들어가고 입구를 찍는다..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/43BVx/dJMcadHGvaU/NgNTAsyKz0HDBhf0rSBByK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F43BVx%2FdJMcadHGvaU%2FNgNTAsyKz0HDBhf0rSBByK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이수중전망대 못들어가고 입구를 찍는다..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfxLE/dJMcagYKrt6/T2rTBxkVSiHUzzGEJ20cEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfxLE/dJMcagYKrt6/T2rTBxkVSiHUzzGEJ20cEK/img.png&quot; data-alt=&quot;피쉬아이 수중전망대 (닫혀있어서 아쉽지만 이렇게 찍음)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfxLE/dJMcagYKrt6/T2rTBxkVSiHUzzGEJ20cEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfxLE%2FdJMcagYKrt6%2FT2rTBxkVSiHUzzGEJ20cEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이 수중전망대 (닫혀있어서 아쉽지만 이렇게 찍음)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2249&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/euJLeU/dJMcadHGvaT/C0tkD2YCSh6vLlQuFUhLOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/euJLeU/dJMcadHGvaT/C0tkD2YCSh6vLlQuFUhLOk/img.png&quot; data-alt=&quot;피쉬아이 수중전망대 근처에서 물놀이 하는 외국인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/euJLeU/dJMcadHGvaT/C0tkD2YCSh6vLlQuFUhLOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeuJLeU%2FdJMcadHGvaT%2FC0tkD2YCSh6vLlQuFUhLOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2249&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2249&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이 수중전망대 근처에서 물놀이 하는 외국인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SIlgZ/dJMcahchsiW/8XffHLmWjpaycck8oO9r0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SIlgZ/dJMcahchsiW/8XffHLmWjpaycck8oO9r0K/img.png&quot; data-alt=&quot;피쉬아이수중전망대&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SIlgZ/dJMcahchsiW/8XffHLmWjpaycck8oO9r0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSIlgZ%2FdJMcahchsiW%2F8XffHLmWjpaycck8oO9r0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이수중전망대&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgbGvg/dJMcafevX8q/2KbfIzDKfGFct2pAHoSyU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgbGvg/dJMcafevX8q/2KbfIzDKfGFct2pAHoSyU0/img.png&quot; data-alt=&quot;파도가 밀려오는 수중전망대 이게 파도라고 해야할지 애매하긴하지만..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgbGvg/dJMcafevX8q/2KbfIzDKfGFct2pAHoSyU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgbGvg%2FdJMcafevX8q%2F2KbfIzDKfGFct2pAHoSyU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파도가 밀려오는 수중전망대 이게 파도라고 해야할지 애매하긴하지만..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d80v3C/dJMcadHGvaS/w8Ox06tOZnIACXiz04JaFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d80v3C/dJMcadHGvaS/w8Ox06tOZnIACXiz04JaFK/img.png&quot; data-alt=&quot;피쉬아이수중전망대를 못간 나의 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d80v3C/dJMcadHGvaS/w8Ox06tOZnIACXiz04JaFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd80v3C%2FdJMcadHGvaS%2Fw8Ox06tOZnIACXiz04JaFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이수중전망대를 못간 나의 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YHNXQ/dJMcahchsiX/69UUwrI6OUXGM9HpN8AkxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YHNXQ/dJMcahchsiX/69UUwrI6OUXGM9HpN8AkxK/img.png&quot; data-alt=&quot;피쉬아이수중전망대 바로 옆 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YHNXQ/dJMcahchsiX/69UUwrI6OUXGM9HpN8AkxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYHNXQ%2FdJMcahchsiX%2F69UUwrI6OUXGM9HpN8AkxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이수중전망대 바로 옆 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sgl7Q/dJMcahchsiY/KHywYeCF2cDuNaZ4uoB011/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sgl7Q/dJMcahchsiY/KHywYeCF2cDuNaZ4uoB011/img.png&quot; data-alt=&quot;피쉬아이수중전망대근처모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sgl7Q/dJMcahchsiY/KHywYeCF2cDuNaZ4uoB011/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSgl7Q%2FdJMcahchsiY%2FKHywYeCF2cDuNaZ4uoB011%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;피쉬아이수중전망대근처모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boi3wx/dJMcaaqHYCL/XmWokLokEbOegG8OWSNGQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boi3wx/dJMcaaqHYCL/XmWokLokEbOegG8OWSNGQk/img.png&quot; data-alt=&quot;스페인광장 아이러브괌 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boi3wx/dJMcaaqHYCL/XmWokLokEbOegG8OWSNGQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fboi3wx%2FdJMcaaqHYCL%2FXmWokLokEbOegG8OWSNGQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 아이러브괌 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C8F4E/dJMcaaRNETU/CLft6p116JLoglKbeogO7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C8F4E/dJMcaaRNETU/CLft6p116JLoglKbeogO7K/img.png&quot; data-alt=&quot;스페인광장 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C8F4E/dJMcaaRNETU/CLft6p116JLoglKbeogO7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC8F4E%2FdJMcaaRNETU%2FCLft6p116JLoglKbeogO7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZyA2H/dJMcaaRNETV/WLGEE6kqaLIWDpAkqQN5S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZyA2H/dJMcaaRNETV/WLGEE6kqaLIWDpAkqQN5S0/img.png&quot; data-alt=&quot;스페인광장 모습 사실 몇분전에 비가 쏟아졌었다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZyA2H/dJMcaaRNETV/WLGEE6kqaLIWDpAkqQN5S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZyA2H%2FdJMcaaRNETV%2FWLGEE6kqaLIWDpAkqQN5S0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 모습 사실 몇분전에 비가 쏟아졌었다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd3weA/dJMcaaqHYCM/nWoF1TH3xk4odeNxocY1p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd3weA/dJMcaaqHYCM/nWoF1TH3xk4odeNxocY1p0/img.png&quot; data-alt=&quot;스페인광장 꽃 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd3weA/dJMcaaqHYCM/nWoF1TH3xk4odeNxocY1p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd3weA%2FdJMcaaqHYCM%2FnWoF1TH3xk4odeNxocY1p0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 꽃 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYp9Uu/dJMcaaYwUzT/avS4z6nJa6RA6aN54cgpjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYp9Uu/dJMcaaYwUzT/avS4z6nJa6RA6aN54cgpjK/img.png&quot; data-alt=&quot;스페인광장 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYp9Uu/dJMcaaYwUzT/avS4z6nJa6RA6aN54cgpjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYp9Uu%2FdJMcaaYwUzT%2FavS4z6nJa6RA6aN54cgpjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vddFA/dJMcaaYwUzU/ZPsiodLYJhGYfSk2uKgGi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vddFA/dJMcaaYwUzU/ZPsiodLYJhGYfSk2uKgGi0/img.png&quot; data-alt=&quot;스페인광장 바로 근처에 있는 성당&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vddFA/dJMcaaYwUzU/ZPsiodLYJhGYfSk2uKgGi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvddFA%2FdJMcaaYwUzU%2FZPsiodLYJhGYfSk2uKgGi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 바로 근처에 있는 성당&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqv6Vz/dJMcaaYwUzV/mXuXFB5aoNdHnT1kas1zXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqv6Vz/dJMcaaYwUzV/mXuXFB5aoNdHnT1kas1zXk/img.png&quot; data-alt=&quot;스페인광장 근처 박물관&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqv6Vz/dJMcaaYwUzV/mXuXFB5aoNdHnT1kas1zXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcqv6Vz%2FdJMcaaYwUzV%2FmXuXFB5aoNdHnT1kas1zXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 근처 박물관&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCo4tC/dJMcaaYwUzW/B6HwJX798xkBbBljnXuWMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCo4tC/dJMcaaYwUzW/B6HwJX798xkBbBljnXuWMk/img.png&quot; data-alt=&quot;스페인광장 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCo4tC/dJMcaaYwUzW/B6HwJX798xkBbBljnXuWMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCo4tC%2FdJMcaaYwUzW%2FB6HwJX798xkBbBljnXuWMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/52aAG/dJMcahi5BNe/iILNl2o6grkJsNiLBeAh0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/52aAG/dJMcahi5BNe/iILNl2o6grkJsNiLBeAh0K/img.png&quot; data-alt=&quot;스페인광장에서 바라본 성당모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/52aAG/dJMcahi5BNe/iILNl2o6grkJsNiLBeAh0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F52aAG%2FdJMcahi5BNe%2FiILNl2o6grkJsNiLBeAh0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스페인광장에서 바라본 성당모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OMQFw/dJMcahi5Dnk/zQTBh59ebi7C6IyiagxIK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OMQFw/dJMcahi5Dnk/zQTBh59ebi7C6IyiagxIK1/img.png&quot; data-alt=&quot;시원하게 펼쳐져있는 사랑의절벽&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OMQFw/dJMcahi5Dnk/zQTBh59ebi7C6IyiagxIK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOMQFw%2FdJMcahi5Dnk%2FzQTBh59ebi7C6IyiagxIK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시원하게 펼쳐져있는 사랑의절벽&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUfmWH/dJMcaaYwVOT/6PxvwzgOzkyd9LizhqJ59k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUfmWH/dJMcaaYwVOT/6PxvwzgOzkyd9LizhqJ59k/img.png&quot; data-alt=&quot;사랑의절벽에 있는 평화기념비&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUfmWH/dJMcaaYwVOT/6PxvwzgOzkyd9LizhqJ59k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUfmWH%2FdJMcaaYwVOT%2F6PxvwzgOzkyd9LizhqJ59k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의절벽에 있는 평화기념비&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zjR1R/dJMcagj8Rpt/aImbjm6zMKvja9k5G8yISk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zjR1R/dJMcagj8Rpt/aImbjm6zMKvja9k5G8yISk/img.png&quot; data-alt=&quot;평화기념비의 안내표지판&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zjR1R/dJMcagj8Rpt/aImbjm6zMKvja9k5G8yISk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzjR1R%2FdJMcagj8Rpt%2FaImbjm6zMKvja9k5G8yISk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;평화기념비의 안내표지판&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260215_015318574_11.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZFFe/dJMcagdo5Rp/NfKYAfAsbxDfpBRfnBZiX0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZFFe/dJMcagdo5Rp/NfKYAfAsbxDfpBRfnBZiX0/img.jpg&quot; data-alt=&quot;사랑의 절벽 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZFFe/dJMcagdo5Rp/NfKYAfAsbxDfpBRfnBZiX0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZFFe%2FdJMcagdo5Rp%2FNfKYAfAsbxDfpBRfnBZiX0%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;4000&quot; height=&quot;2252&quot; data-filename=&quot;KakaoTalk_20260215_015318574_11.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEIYiq/dJMcagj8Rpy/bxKTIHBAcE1u13xrHKPCIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEIYiq/dJMcagj8Rpy/bxKTIHBAcE1u13xrHKPCIk/img.png&quot; data-alt=&quot;사랑의절벽 사랑의 종&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEIYiq/dJMcagj8Rpy/bxKTIHBAcE1u13xrHKPCIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEIYiq%2FdJMcagj8Rpy%2FbxKTIHBAcE1u13xrHKPCIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의절벽 사랑의 종&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgiaMH/dJMcaaYwVOS/6cEMSA0axkb5nn7jRkpT30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgiaMH/dJMcaaYwVOS/6cEMSA0axkb5nn7jRkpT30/img.png&quot; data-alt=&quot;사랑의 절벽 일몰&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgiaMH/dJMcaaYwVOS/6cEMSA0axkb5nn7jRkpT30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgiaMH%2FdJMcaaYwVOS%2F6cEMSA0axkb5nn7jRkpT30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 일몰&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DnMyx/dJMcaaYwVOV/hy0yXOMMtJ6nhaIafiZrSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DnMyx/dJMcaaYwVOV/hy0yXOMMtJ6nhaIafiZrSk/img.png&quot; data-alt=&quot;사랑의 절벽 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DnMyx/dJMcaaYwVOV/hy0yXOMMtJ6nhaIafiZrSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDnMyx%2FdJMcaaYwVOV%2Fhy0yXOMMtJ6nhaIafiZrSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MRDP9/dJMcagj8Rpu/FtSOv9SZoJyYxedEfzrmk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MRDP9/dJMcagj8Rpu/FtSOv9SZoJyYxedEfzrmk0/img.png&quot; data-alt=&quot;사랑의절벽 자물쇠&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MRDP9/dJMcagj8Rpu/FtSOv9SZoJyYxedEfzrmk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMRDP9%2FdJMcagj8Rpu%2FFtSOv9SZoJyYxedEfzrmk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의절벽 자물쇠&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lXAAO/dJMcaaYwVOR/2Cz4xT4XqY5SJK9RWbJqMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lXAAO/dJMcaaYwVOR/2Cz4xT4XqY5SJK9RWbJqMk/img.png&quot; data-alt=&quot;사랑의절벽에는 비행기도 다니는것을 볼 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lXAAO/dJMcaaYwVOR/2Cz4xT4XqY5SJK9RWbJqMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlXAAO%2FdJMcaaYwVOR%2F2Cz4xT4XqY5SJK9RWbJqMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의절벽에는 비행기도 다니는것을 볼 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsOexu/dJMcahi5Dnl/z3Fxwi7mxI1w1M5ixFQUD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsOexu/dJMcahi5Dnl/z3Fxwi7mxI1w1M5ixFQUD1/img.png&quot; data-alt=&quot;사랑의절벽 해가 지기 시작한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsOexu/dJMcahi5Dnl/z3Fxwi7mxI1w1M5ixFQUD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsOexu%2FdJMcahi5Dnl%2Fz3Fxwi7mxI1w1M5ixFQUD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의절벽 해가 지기 시작한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEZKgY/dJMcaaYwVOW/ulBtzVoyg0qww6s0FMGvB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEZKgY/dJMcaaYwVOW/ulBtzVoyg0qww6s0FMGvB1/img.png&quot; data-alt=&quot;멍 때리고 보면 좋다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEZKgY/dJMcaaYwVOW/ulBtzVoyg0qww6s0FMGvB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEZKgY%2FdJMcaaYwVOW%2FulBtzVoyg0qww6s0FMGvB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;멍 때리고 보면 좋다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k06xG/dJMcagj8Rpw/zL0pT0aeOGQedIBeGacuX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k06xG/dJMcagj8Rpw/zL0pT0aeOGQedIBeGacuX1/img.png&quot; data-alt=&quot;바로 아래 보면 해변같이 모래도 있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k06xG/dJMcagj8Rpw/zL0pT0aeOGQedIBeGacuX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk06xG%2FdJMcagj8Rpw%2FzL0pT0aeOGQedIBeGacuX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;바로 아래 보면 해변같이 모래도 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bciMLW/dJMcagj8Rpv/7iZA98yMhAXckxYXII29ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bciMLW/dJMcagj8Rpv/7iZA98yMhAXckxYXII29ck/img.png&quot; data-alt=&quot;사랑의 절벽 입장권&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bciMLW/dJMcagj8Rpv/7iZA98yMhAXckxYXII29ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbciMLW%2FdJMcagj8Rpv%2F7iZA98yMhAXckxYXII29ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 입장권&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kDsSr/dJMcaaYwVOX/OquacE69G9uUK7S2M4PKb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kDsSr/dJMcaaYwVOX/OquacE69G9uUK7S2M4PKb1/img.png&quot; data-alt=&quot;사랑의 절벽 입구에 있는 하트 조형물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kDsSr/dJMcaaYwVOX/OquacE69G9uUK7S2M4PKb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkDsSr%2FdJMcaaYwVOX%2FOquacE69G9uUK7S2M4PKb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 입구에 있는 하트 조형물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdRjXV/dJMcahi5Dnn/4KkhQuyqLgR6sgOTPWlt8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdRjXV/dJMcahi5Dnn/4KkhQuyqLgR6sgOTPWlt8K/img.png&quot; data-alt=&quot;사랑의 절벽 건물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdRjXV/dJMcahi5Dnn/4KkhQuyqLgR6sgOTPWlt8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdRjXV%2FdJMcahi5Dnn%2F4KkhQuyqLgR6sgOTPWlt8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 건물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cv8Zft/dJMcahi5Dnm/jSAsK1DSs4PWYzRpXewTL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cv8Zft/dJMcahi5Dnm/jSAsK1DSs4PWYzRpXewTL0/img.png&quot; data-alt=&quot;사랑의 절벽 우연히 찍었는데 이쁘다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cv8Zft/dJMcahi5Dnm/jSAsK1DSs4PWYzRpXewTL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcv8Zft%2FdJMcahi5Dnm%2FjSAsK1DSs4PWYzRpXewTL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의 절벽 우연히 찍었는데 이쁘다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260215_015318574_10.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UiVoG/dJMcafr0dq0/MpZIlcIK53yyxQMfF0gIa0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UiVoG/dJMcafr0dq0/MpZIlcIK53yyxQMfF0gIa0/img.jpg&quot; data-alt=&quot;사랑의절벽&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UiVoG/dJMcafr0dq0/MpZIlcIK53yyxQMfF0gIa0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUiVoG%2FdJMcafr0dq0%2FMpZIlcIK53yyxQMfF0gIa0%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;4000&quot; height=&quot;2252&quot; data-filename=&quot;KakaoTalk_20260215_015318574_10.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사랑의절벽&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CpHxH/dJMcaaRNGgB/bmCooWH6ZaNF7QctjOGjE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CpHxH/dJMcaaRNGgB/bmCooWH6ZaNF7QctjOGjE0/img.png&quot; data-alt=&quot;건비치 야경 너무 이쁘다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CpHxH/dJMcaaRNGgB/bmCooWH6ZaNF7QctjOGjE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCpHxH%2FdJMcaaRNGgB%2FbmCooWH6ZaNF7QctjOGjE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치 야경 너무 이쁘다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RAOGO/dJMb99SRhiI/4r4plsY1EvKMh6M5E7aw80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RAOGO/dJMb99SRhiI/4r4plsY1EvKMh6M5E7aw80/img.png&quot; data-alt=&quot;건비치에서도 비행기가 지나가는게 보인다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RAOGO/dJMb99SRhiI/4r4plsY1EvKMh6M5E7aw80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRAOGO%2FdJMb99SRhiI%2F4r4plsY1EvKMh6M5E7aw80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치에서도 비행기가 지나가는게 보인다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xOGlc/dJMcaaRNGgD/knLm8E6jINyRiElukUorCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xOGlc/dJMcaaRNGgD/knLm8E6jINyRiElukUorCK/img.png&quot; data-alt=&quot;건비치에 위치하고 있는 레스토랑&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xOGlc/dJMcaaRNGgD/knLm8E6jINyRiElukUorCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxOGlc%2FdJMcaaRNGgD%2FknLm8E6jINyRiElukUorCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치에 위치하고 있는 레스토랑&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDBSib/dJMcabQFsBD/JOoKD1OUO6URJ9q1kICfuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDBSib/dJMcabQFsBD/JOoKD1OUO6URJ9q1kICfuK/img.png&quot; data-alt=&quot;건비치로 들어가는중&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDBSib/dJMcabQFsBD/JOoKD1OUO6URJ9q1kICfuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDBSib%2FdJMcabQFsBD%2FJOoKD1OUO6URJ9q1kICfuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치로 들어가는중&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2249&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kg7Ms/dJMb99SRhiM/Bqyr3b7jyQnZAZHsAPyFH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kg7Ms/dJMb99SRhiM/Bqyr3b7jyQnZAZHsAPyFH1/img.png&quot; data-alt=&quot;건비치에서 여유를 즐기며 놀고 있는 사람들 부럽다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kg7Ms/dJMb99SRhiM/Bqyr3b7jyQnZAZHsAPyFH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKg7Ms%2FdJMb99SRhiM%2FBqyr3b7jyQnZAZHsAPyFH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2249&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2249&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치에서 여유를 즐기며 놀고 있는 사람들 부럽다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkjM2F/dJMb99SRhiN/P4OFwmKf7WnJeFittgowX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkjM2F/dJMb99SRhiN/P4OFwmKf7WnJeFittgowX0/img.png&quot; data-alt=&quot;건비치 야경 진짜 이쁘다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkjM2F/dJMb99SRhiN/P4OFwmKf7WnJeFittgowX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkjM2F%2FdJMb99SRhiN%2FP4OFwmKf7WnJeFittgowX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치 야경 진짜 이쁘다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFxdu/dJMcaaEfPKq/82fMUivC7KHKdit8T49qQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFxdu/dJMcaaEfPKq/82fMUivC7KHKdit8T49qQ0/img.png&quot; data-alt=&quot;저기서 음식은 맛있게 먹을듯&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFxdu/dJMcaaEfPKq/82fMUivC7KHKdit8T49qQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFxdu%2FdJMcaaEfPKq%2F82fMUivC7KHKdit8T49qQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;저기서 음식은 맛있게 먹을듯&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1wqH5/dJMcabwmHVj/5ZzSCVspWzAB5kXgmIjrk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1wqH5/dJMcabwmHVj/5ZzSCVspWzAB5kXgmIjrk1/img.png&quot; data-alt=&quot;건비치 해변&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1wqH5/dJMcabwmHVj/5ZzSCVspWzAB5kXgmIjrk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1wqH5%2FdJMcabwmHVj%2F5ZzSCVspWzAB5kXgmIjrk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건비치 해변&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wcHWv/dJMcaaqHZYU/FLvusZe568drkbi2kViLmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wcHWv/dJMcaaqHZYU/FLvusZe568drkbi2kViLmK/img.png&quot; data-alt=&quot;괌 리조트 근처에 있는 놀이동산&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wcHWv/dJMcaaqHZYU/FLvusZe568drkbi2kViLmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwcHWv%2FdJMcaaqHZYU%2FFLvusZe568drkbi2kViLmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;괌 리조트 근처에 있는 놀이동산&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wmOTq/dJMcahXFqSQ/dMBOiDTflrsQjTxvoBqui1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wmOTq/dJMcahXFqSQ/dMBOiDTflrsQjTxvoBqui1/img.png&quot; data-alt=&quot;디스코팡팡도 있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wmOTq/dJMcahXFqSQ/dMBOiDTflrsQjTxvoBqui1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwmOTq%2FdJMcahXFqSQ%2FdMBOiDTflrsQjTxvoBqui1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디스코팡팡도 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMcEnR/dJMcahXFqSP/7QywQUKzDdIKC0NJO9wLD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMcEnR/dJMcahXFqSP/7QywQUKzDdIKC0NJO9wLD1/img.png&quot; data-alt=&quot;바이킹 조명 화려함&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMcEnR/dJMcahXFqSP/7QywQUKzDdIKC0NJO9wLD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMcEnR%2FdJMcahXFqSP%2F7QywQUKzDdIKC0NJO9wLD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;바이킹 조명 화려함&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU4CR1/dJMcaaqHZYV/l7FMifD8f0Rdk1TqQNT4o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU4CR1/dJMcaaqHZYV/l7FMifD8f0Rdk1TqQNT4o1/img.png&quot; data-alt=&quot;이 날 투몬거리에서 행사를 한다고 경찰이 거리 일부를 통제했다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU4CR1/dJMcaaqHZYV/l7FMifD8f0Rdk1TqQNT4o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU4CR1%2FdJMcaaqHZYV%2Fl7FMifD8f0Rdk1TqQNT4o1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이 날 투몬거리에서 행사를 한다고 경찰이 거리 일부를 통제했다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfWElP/dJMcacPBaBr/fC4IGukCZJ9AwrsB9zJ170/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfWElP/dJMcacPBaBr/fC4IGukCZJ9AwrsB9zJ170/img.png&quot; data-alt=&quot;미국이긴 하다.. 펄럭펄럭 성조기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfWElP/dJMcacPBaBr/fC4IGukCZJ9AwrsB9zJ170/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfWElP%2FdJMcacPBaBr%2FfC4IGukCZJ9AwrsB9zJ170%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;미국이긴 하다.. 펄럭펄럭 성조기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 여행을 마치며&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1kuAL/dJMcadVdHq9/KPcQE1ZHsWji2Vj8D2TIJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1kuAL/dJMcadVdHq9/KPcQE1ZHsWji2Vj8D2TIJ1/img.png&quot; data-alt=&quot;한국 거의 다 도착했을 때 비행기에서 찍었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1kuAL/dJMcadVdHq9/KPcQE1ZHsWji2Vj8D2TIJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1kuAL%2FdJMcadVdHq9%2FKPcQE1ZHsWji2Vj8D2TIJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;872&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한국 거의 다 도착했을 때 비행기에서 찍었다.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;월요일 아침, 다시 김해공항에 도착했을 때의 그 쌀쌀한 공기는 현실 복귀를 알리는 신호 같았습니다. 3박 5일이라는 짧은 시간이었지만, 괌은 생각보다 많은 것을 보여주었습니다. 높은 환율과 물가가 부담스럽긴 하지만, 한국에서 가장 편하게 다녀올 수 있는 미국이라는 점, 그리고 렌트카 하나면 어디든 갈 수 있는 자유로움은 여전히 매력적입니다.&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin-text&quot; data-ke-size=&quot;size16&quot;&gt;혹시 2025년에 괌 여행을 계획하고 계신다면, 너무 빡빡한 일정보다는 날씨에 따라 유동적으로 움직일 수 있는 여유를 두시길 권합니다. 그리고 돈키호테는 꼭 밤늦게 가보세요. 텅 빈 매장을 전세 낸 것처럼 쇼핑하는 재미가 쏠쏠합니다. 이번 워크샵 겸 여행 기록이 여러분의 괌 여행 준비에 조금이나마 도움이 되었기를 바랍니다.&lt;/p&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>괌3박5일</category>
      <category>괌돈키호테</category>
      <category>괌렌트카</category>
      <category>괌맛집</category>
      <category>괌쇼핑</category>
      <category>괌여행</category>
      <category>괌자유여행</category>
      <category>부산출발괌</category>
      <category>사랑의절벽</category>
      <category>직장인워크샵</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/571</guid>
      <comments>https://odinbox.tistory.com/571#entry571comment</comments>
      <pubDate>Sun, 15 Feb 2026 18:49:47 +0900</pubDate>
    </item>
    <item>
      <title>왜 긁어 부스럼을 만드냐고요? 혁신을 위해서입니다.</title>
      <link>https://odinbox.tistory.com/570</link>
      <description>&lt;div&gt;
&lt;style&gt;
    :root {
        --odin-accent : #0056b3;   /* 신뢰감을 주는 딥 블루 */
        --odin-dark : #212529;     /* 본문 기본 색상 */
        --odin-gray : #6c757d;     /* 보조 텍스트 */
        --odin-bg : #ffffff;       /* 배경색 */
        --odin-light-bg : #f8f9fa; /* 카드 배경색 */
        --odin-border : #dee2e6;   /* 테두리 색상 */
    }

    .ODINLIFEISGOOD_container {
        font-family : 'Pretendard', -apple-system, BlinkMacSystemFont, 'Malgun Gothic', sans-serif;
        line-height : 1.75;
        color : var(--odin-dark);
        max-width : 880px;
        margin : 0 auto;
        padding : 30px 20px 50px; /* 상단 패딩 조정 */
        background-color : var(--odin-bg);
        word-break : keep-all; /* 한글 가독성 최적화 */
    }

    /* 썸네일 이미지 스타일 */
    .ODINLIFEISGOOD_thumbnail {
        margin-bottom : 40px;
        text-align : center;
    }
    
    .ODINLIFEISGOOD_thumbnail img {
        max-width : 100%;
        height : auto;
        border-radius : 12px;
        box-shadow : 0 10px 25px rgba(0,0,0,0.1);
    }

    /* 애니메이션 효과 */
    .ODINLIFEISGOOD_fade_in {
        opacity : 0;
        transform : translateY(20px);
        transition : opacity 0.8s ease, transform 0.8s ease;
    }

    .ODINLIFEISGOOD_fade_in.ODINLIFEISGOOD_active {
        opacity : 1;
        transform : translateY(0);
    }

    /* 헤더 스타일 */
    .ODINLIFEISGOOD_header {
        margin-bottom : 60px;
        border-bottom : 2px solid var(--odin-dark);
        padding-bottom : 30px;
        text-align : center;
    }

    .ODINLIFEISGOOD_header h2 { /* 부제 */
        font-size : 1.3rem;
        color : var(--odin-gray);
        font-weight : 600;
        margin-top : 15px;
    }

    /* 섹션 공통 스타일 */
    .ODINLIFEISGOOD_section_title {
        font-size : 1.6rem;
        color : var(--odin-accent);
        margin-top : 80px;
        margin-bottom : 25px;
        font-weight : 700;
        display : flex;
        align-items : center;
    }

    .ODINLIFEISGOOD_section_title::before {
        content : '';
        display : block;
        width : 6px;
        height : 24px;
        background-color : var(--odin-accent);
        margin-right : 12px;
    }

    .ODINLIFEISGOOD_paragraph {
        margin-bottom : 24px;
        text-align : justify;
        font-size : 1.05rem;
        color : #333;
    }

    /* 하이라이트 및 코드박스 */
    .ODINLIFEISGOOD_highlight {
        font-weight : 700;
        color : var(--odin-accent);
        background : rgba(0, 86, 179, 0.05);
        padding : 2px 4px;
        border-radius : 4px;
    }

    .ODINLIFEISGOOD_code_box {
        background-color : #2b3035;
        color : #f8f9fa;
        padding : 25px;
        border-radius : 8px;
        font-family : 'Consolas', monospace;
        font-size : 0.95rem;
        margin : 30px 0;
        border-left : 5px solid var(--odin-accent);
        position : relative;
    }

    .ODINLIFEISGOOD_code_box::after {
        content : 'Dev_Log.cs';
        position : absolute;
        top : 10px;
        right : 15px;
        font-size : 0.8rem;
        color : #6c757d;
        opacity : 0.8;
    }

    /* 아카이브 그리드 스타일 */
    .ODINLIFEISGOOD_archive_grid {
        display : grid;
        grid-template-columns : repeat(auto-fit, minmax(280px, 1fr));
        gap : 20px;
        margin-top : 30px;
    }

    .ODINLIFEISGOOD_archive_card {
        background : var(--odin-light-bg);
        border : 1px solid var(--odin-border);
        padding : 25px;
        border-radius : 12px;
        transition : all 0.3s ease;
    }

    .ODINLIFEISGOOD_archive_card:hover {
        border-color : var(--odin-accent);
        transform : translateY(-5px);
        box-shadow : 0 5px 15px rgba(0,0,0,0.05);
    }

    .ODINLIFEISGOOD_cat_title {
        font-size : 1.2rem;
        font-weight : 800;
        color : #111;
        margin-bottom : 15px;
        display : block;
        border-bottom : 1px solid #ddd;
        padding-bottom : 10px;
    }

    .ODINLIFEISGOOD_sub_cat {
        display : flex;
        flex-wrap : wrap;
        gap : 8px;
        margin-top : 10px;
    }

    .ODINLIFEISGOOD_badge {
        font-size : 0.85rem;
        background : #fff;
        border : 1px solid #ccc;
        padding : 4px 10px;
        border-radius : 4px;
        color : #555;
        font-weight : 500;
    }

    /* 푸터 스타일 */
    .ODINLIFEISGOOD_footer {
        margin-top : 100px;
        padding : 60px 20px;
        background-color : var(--odin-light-bg);
        border-top : 1px solid var(--odin-border);
        text-align : center;
        border-radius : 12px;
    }

    .ODINLIFEISGOOD_footer h3 {
        font-size : 1.8rem;
        color : var(--odin-accent);
        margin-bottom : 15px;
    }

    .ODINLIFEISGOOD_tag_cloud {
        display : flex;
        flex-wrap : wrap;
        justify-content : center;
        gap : 8px;
        margin-top : 25px;
    }

    .ODINLIFEISGOOD_tag {
        font-size : 0.9rem;
        color : #fff;
        background : var(--odin-accent);
        padding : 6px 14px;
        border-radius : 20px;
        opacity : 0.9;
    }
&lt;/style&gt;
&lt;/div&gt;
&lt;article class=&quot;ODINLIFEISGOOD_container&quot;&gt;
&lt;div class=&quot;ODINLIFEISGOOD_thumbnail ODINLIFEISGOOD_fade_in&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRwcDP/dJMcajuhecy/6wsfYWwERgeKRaCTB5pmak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRwcDP/dJMcajuhecy/6wsfYWwERgeKRaCTB5pmak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRwcDP/dJMcajuhecy/6wsfYWwERgeKRaCTB5pmak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRwcDP%2FdJMcajuhecy%2F6wsfYWwERgeKRaCTB5pmak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;header class=&quot;ODINLIFEISGOOD_header ODINLIFEISGOOD_fade_in&quot;&gt;
&lt;p style=&quot;font-weight: bold; color: var(--odin-accent); margin-bottom: 10px;&quot; data-ke-size=&quot;size16&quot;&gt;Developer Retrospective &amp;middot; 2022-2026&lt;/p&gt;

&lt;h2 data-ke-size=&quot;size26&quot;&gt;레거시와 혁신 사이, 울산 토박이 개발자의 4년 성장 로그&lt;/h2&gt;
&lt;/header&gt;
&lt;section class=&quot;ODINLIFEISGOOD_fade_in&quot;&gt;
&lt;div class=&quot;ODINLIFEISGOOD_section_title&quot;&gt;01. Initialize : 절실함이라는 동력&lt;/div&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;어린 시절 저는 컴퓨터 본체를 분해하고 &lt;span class=&quot;ODINLIFEISGOOD_highlight&quot;&gt;비주얼베이직(Visual Basic)&lt;/span&gt;으로 화면을 그리던 공학도 꿈나무였습니다. &lt;b&gt;울산정보영재&lt;/b&gt;에 합격하며 확신을 얻었지만, 사춘기라는 예기치 못한 버그(Bug)를 만나 학교 밖 청소년이 되는 시련을 겪기도 했습니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;뒤늦은 대학 입학 후에도 현실은 녹록지 않았습니다. 학비를 위해 마트 배달, 철물점, 막노동을 전전해야 했고, 특히 &lt;b&gt;엔진오일 생산 공장&lt;/b&gt;에서 땀 흘리던 시절은 제 인생의 전환점이 되었습니다. &quot;지금 이 루프(Loop)를 끊지 않으면 미래는 없다&quot;는 절박함이 저를 다시 키보드 앞으로 이끌었고, 그 시절의 끈기는 지금 제가 어려운 코드를 마주했을 때 버티는 힘이 되었습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;ODINLIFEISGOOD_fade_in&quot;&gt;
&lt;div class=&quot;ODINLIFEISGOOD_section_title&quot;&gt;02. Exception Handling : 신입의 생존 전략&lt;/div&gt;
&lt;div class=&quot;ODINLIFEISGOOD_code_box&quot;&gt;// 2022년 입사 초기 상태&lt;br /&gt;try {&lt;br /&gt;&amp;nbsp;&amp;nbsp;LegacySystem.Analyze();&lt;br /&gt;} catch (PanicException e) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;Health.Status = &quot;Critical&quot;; // 3개월간 위장 장애&lt;br /&gt;&amp;nbsp;&amp;nbsp;Strategy = &quot;Reverse_Engineering&quot;; // 코드 역분석으로 돌파&lt;br /&gt;}&lt;/div&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;2022년 6월 1일, 첫 출근의 설렘은 곧 두려움으로 바뀌었습니다. 학교에서 배우지 못한 &lt;span class=&quot;ODINLIFEISGOOD_highlight&quot;&gt;.NET 레거시 시스템&lt;/span&gt;과 문서화되지 않은 히스토리는 신입에게 거대한 장벽이었습니다. 그리고 말 못한 묘한 정치의 느낌과 함께 입사 초기 3개월은 극심한 압박감에 매일 점심마다 체하기 일쑤였습니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;하지만 저는 도망치지 않았습니다. 남들이 기피하는 레거시 코드를 한 줄 한 줄 역분석하고, 공식 문서를 파고들며 비즈니스 로직을 몸으로 익혔습니다. 그 결과, 점차 팀 내에서 기술적인 신뢰를 쌓으며 그리고 버텼습니다. 그렇게 버티면서 제 자리를 찾아갈 수 있었습니다. 사실 아직까지도 사람과의 관계에서 스트레스가 오긴 하지만 모두가 나를 좋아할 수 없고 이런 일 저런 일이 있다고 생각하며 버티고 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;ODINLIFEISGOOD_fade_in&quot;&gt;
&lt;div class=&quot;ODINLIFEISGOOD_section_title&quot;&gt;03. Core Logic : &quot;왜 긁어 부스럼을 만드냐고요?&quot;&lt;/div&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;지난 4년간 저는 단순한 코더(Coder)에서 문제를 해결하는 엔지니어(Engineer)로 성장했습니다. 특히 제조 현장의 핵심인 &lt;b&gt;MES, ERP, QMS&lt;/b&gt; 시스템을 구축하며, 보수적인 환경에 새로운 기술을 도입하는 '혁신'을 시도했습니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;&quot;잘 돌아가는 시스템에 왜 긁어 부스럼을 만드냐&quot;는 내부적인 우려도 있었습니다. 하지만 저는 대용량 트랜잭션이 발생하는 환경에서 &lt;span class=&quot;ODINLIFEISGOOD_highlight&quot;&gt;PostgreSQL과 Oracle의 쿼리 최적화(Tuning)&lt;/span&gt;를 통해 시스템 응답 속도를 획기적으로 개선하고 데이터 무결성을 확보함으로써, 기술 혁신이 곧 업무 효율로 이어진다는 것을 증명해냈습니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;최근에는 &lt;b&gt;탄소중립 모니터링&lt;/b&gt; 및 &lt;b&gt;금형 추적 시스템&lt;/b&gt;에 &lt;b&gt;AI 기술&lt;/b&gt;을 접목하는 등, 현재에 안주하지 않고 기술 도메인을 지속적으로 확장하고 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;ODINLIFEISGOOD_fade_in&quot;&gt;
&lt;div class=&quot;ODINLIFEISGOOD_section_title&quot;&gt;04. OdinBOX Archive : 기록이 성장이 되는 공간&lt;/div&gt;
&lt;p class=&quot;ODINLIFEISGOOD_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;지식의 휘발성을 막기 위해 시작한 블로그 &lt;b&gt;OdinBOX&lt;/b&gt;는 이제 제 삶의 일부이자 기술 부채를 상환하는 창구입니다. 개발하며 마주한 문제들의 해결책과 울산에서의 일상을 아래 카테고리에 꾸준히 기록하고 있습니다.&lt;/p&gt;
&lt;div class=&quot;ODINLIFEISGOOD_archive_grid&quot;&gt;
&lt;div class=&quot;ODINLIFEISGOOD_archive_card&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_cat_title&quot;&gt;DEVELOPMENT&lt;/span&gt;
&lt;p style=&quot;font-size: 0.95rem; color: #555; margin-bottom: 15px;&quot; data-ke-size=&quot;size16&quot;&gt;. NET, DB 최적화 등 실무에서 부딪히며 배운 기술적 인사이트와 트러블 슈팅 기록과 새로운 기술을 배우는 기록입니다.&lt;/p&gt;
&lt;div class=&quot;ODINLIFEISGOOD_sub_cat&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Working-level DB&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Server Side&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Clientside&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;ODINLIFEISGOOD_archive_card&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_cat_title&quot;&gt;IT &amp;amp; REVIEW&lt;/span&gt;
&lt;p style=&quot;font-size: 0.95rem; color: #555; margin-bottom: 15px;&quot; data-ke-size=&quot;size16&quot;&gt;개발자의 시선으로 분석한 내돈내산 IT 기기 리뷰와 소프트웨어 이야기입니다.&lt;/p&gt;
&lt;div class=&quot;ODINLIFEISGOOD_sub_cat&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Product Review&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;IT Trend&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;SW/GAME&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;ODINLIFEISGOOD_archive_card&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_cat_title&quot;&gt;DAILY ROUTINE&lt;/span&gt;
&lt;p style=&quot;font-size: 0.95rem; color: #555; margin-bottom: 15px;&quot; data-ke-size=&quot;size16&quot;&gt;울산 토박이의 지역 이야기와 차량 관리 등 소소한 일상의 기록입니다.&lt;/p&gt;
&lt;div class=&quot;ODINLIFEISGOOD_sub_cat&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Ulsan Life&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Car&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_badge&quot;&gt;Economy&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;footer class=&quot;ODINLIFEISGOOD_footer ODINLIFEISGOOD_fade_in&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Keep Coding, Keep Innovating&lt;/h3&gt;
&lt;p style=&quot;color: #555; margin-bottom: 25px; font-size: 1.05rem;&quot; data-ke-size=&quot;size16&quot;&gt;울산광역시 블로그 기자단 및 울주군 서포터즈로서 지역 사회와 소통하며,&lt;br /&gt;변화를 두려워하지 않는 '대체 불가능한 개발자'가 되겠습니다.&lt;/p&gt;
&lt;div class=&quot;ODINLIFEISGOOD_tag_cloud&quot;&gt;&lt;span class=&quot;ODINLIFEISGOOD_tag&quot;&gt;#FullStack&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_tag&quot;&gt;#.NET_Core&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_tag&quot;&gt;#MES_Expert&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_tag&quot;&gt;#DB_Tuning&lt;/span&gt; &lt;span class=&quot;ODINLIFEISGOOD_tag&quot;&gt;#Tech_Innovation&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;margin-top: 40px; font-size: 0.85rem; color: #999;&quot; data-ke-size=&quot;size16&quot;&gt;Copyright &amp;copy; 2026 OdinBOX. All rights reserved.&lt;/p&gt;
&lt;/footer&gt;&lt;/article&gt;
&lt;script&gt;
    (function() {
        const observer = new IntersectionObserver((entries) =&gt; {
            entries.forEach(entry =&gt; {
                if (entry.isIntersecting) {
                    entry.target.classList.add('ODINLIFEISGOOD_active');
                }
            });
        }, { threshold : 0.1 });

        document.querySelectorAll('.ODINLIFEISGOOD_fade_in').forEach(el =&gt; {
            observer.observe(el);
        });
    })();
&lt;/script&gt;</description>
      <category>DailyRoutine</category>
      <category>dotnet</category>
      <category>개발자회고</category>
      <category>기술혁신</category>
      <category>성장</category>
      <category>성장로그</category>
      <category>솔루션개발</category>
      <category>울산</category>
      <category>울산개발자</category>
      <category>울주군</category>
      <category>최영환</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/570</guid>
      <comments>https://odinbox.tistory.com/570#entry570comment</comments>
      <pubDate>Sat, 31 Jan 2026 15:58:05 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL 논리복제와 FDW로 운영 서버를 두 번 죽여본 개발자의 실시간 데이터 동기화 생존기</title>
      <link>https://odinbox.tistory.com/569</link>
      <description>&lt;div&gt;
&lt;style&gt;
  .pg-article {
    font-family : 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    line-height : 1.8;
    color : #333;
    max-width : 100%;
  }
  .pg-article h1 {
    font-size : 1.8em;
    font-weight : 700;
    margin-bottom : 10px;
    color : #1a1a2e;
  }
  .pg-article h2 {
    font-size : 1.5em;
    font-weight : 700;
    margin : 50px 0 25px 0;
    color : #1a1a2e;
  }
  .pg-article h3 {
    font-size : 1.25em;
    font-weight : 600;
    margin : 30px 0 15px 0;
    color : #333;
  }
  .pg-article h4 {
    font-size : 1.1em;
    font-weight : 600;
    margin : 20px 0 12px 0;
    color : #444;
  }
  .pg-subtitle {
    color : #6c757d;
    font-size : 1.1em;
    margin-bottom : 30px;
  }
  .pg-card {
    background : #fff;
    border-radius : 12px;
    padding : 25px;
    margin : 20px 0;
    box-shadow : 0 2px 12px rgba(0,0,0,0.08);
    border : 1px solid #e9ecef;
  }
  .pg-card-danger { border-left : 4px solid #dc3545; }
  .pg-card-warning { border-left : 4px solid #ffc107; }
  .pg-card-success { border-left : 4px solid #28a745; }
  .pg-card-info { border-left : 4px solid #007bff; }
  .pg-card-purple { border-left : 4px solid #6f42c1; }
  .pg-card-teal { border-left : 4px solid #20c997; }
  .pg-card-orange { border-left : 4px solid #fd7e14; }
  .pg-grid-2 {
    display : grid;
    grid-template-columns : repeat(2, 1fr);
    gap : 20px;
    margin : 20px 0;
  }
  @media (max-width : 768px) {
    .pg-grid-2 { grid-template-columns : 1fr; }
  }
  .pg-info-box {
    background : #f8f9fa;
    border-radius : 12px;
    padding : 20px;
  }
  .pg-info-box h4 {
    margin : 0 0 15px 0;
    font-size : 1.1em;
  }
  .pg-alert {
    padding : 20px;
    border-radius : 12px;
    margin : 20px 0;
  }
  .pg-alert-danger {
    background : linear-gradient(135deg, #fff5f5 0%, #ffe3e3 100%);
    border : 1px solid #f5c2c7;
  }
  .pg-alert-danger h4 { color : #dc3545; margin : 0 0 10px 0; }
  .pg-alert-success {
    background : linear-gradient(135deg, #f0fff4 0%, #d3f9d8 100%);
    border : 1px solid #b2f2bb;
  }
  .pg-alert-success h4 { color : #28a745; margin : 0 0 10px 0; }
  .pg-alert-info {
    background : linear-gradient(135deg, #e7f5ff 0%, #d0ebff 100%);
    border : 1px solid #a5d8ff;
  }
  .pg-alert-info h4 { color : #007bff; margin : 0 0 10px 0; }
  .pg-code {
    background : #1e1e1e;
    color : #d4d4d4;
    padding : 20px;
    border-radius : 8px;
    overflow-x : auto;
    font-family : 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size : 0.9em;
    line-height : 1.6;
    margin : 15px 0;
    white-space : pre;
    word-wrap : break-word;
  }
  .pg-code .comment { color : #6a9955; }
  .pg-code .keyword { color : #569cd6; }
  .pg-code .string { color : #ce9178; }
  .pg-code .function { color : #dcdcaa; }
  .pg-code .error { color : #f44747; }
  .pg-code .highlight { color : #4ec9b0; }
  .pg-gauge-container {
    background : #f8f9fa;
    border-radius : 12px;
    padding : 20px;
    text-align : center;
  }
  .pg-gauge-title {
    font-weight : 600;
    margin-bottom : 15px;
    color : #dc3545;
  }
  .pg-gauge-bar {
    height : 20px;
    background : #e9ecef;
    border-radius : 10px;
    overflow : hidden;
    margin-bottom : 15px;
  }
  .pg-gauge-fill {
    height : 100%;
    background : linear-gradient(90deg, #ffc107, #fd7e14, #dc3545);
    border-radius : 10px;
    animation : pulse 2s ease-in-out infinite;
  }
  @keyframes pulse {
    0%, 100% { opacity : 1; }
    50% { opacity : 0.7; }
  }
  .pg-gauge-text {
    font-size : 0.95em;
    color : #6c757d;
    font-style : italic;
  }
  .pg-table {
    width : 100%;
    border-collapse : collapse;
    margin : 20px 0;
    border-radius : 8px;
    overflow : hidden;
    box-shadow : 0 2px 8px rgba(0,0,0,0.1);
  }
  .pg-table th {
    background : #343a40;
    color : white;
    padding : 15px;
    text-align : left;
    font-weight : 600;
  }
  .pg-table td {
    padding : 12px 15px;
    border-bottom : 1px solid #e9ecef;
  }
  .pg-table tr:nth-child(even) { background : #f8f9fa; }
  .pg-table tr:hover { background : #e3f2fd; }
  .pg-list {
    list-style : none;
    padding : 0;
    margin : 0;
  }
  .pg-list li {
    padding : 10px 0;
    display : flex;
    align-items : flex-start;
    gap : 12px;
    border-bottom : 1px solid #f1f3f4;
  }
  .pg-list li:last-child { border-bottom : none; }
  .pg-list-icon {
    flex-shrink : 0;
    width : 24px;
    text-align : center;
    font-weight : bold;
  }
  .pg-diagram {
    background : linear-gradient(135deg, #1a1a2e, #16213e);
    color : #e9ecef;
    padding : 25px;
    border-radius : 12px;
    font-family : 'Consolas', monospace;
    font-size : 0.85em;
    overflow-x : auto;
    line-height : 1.5;
    margin : 20px 0;
    white-space : pre;
    word-wrap : break-word;
  }
  .pg-quote {
    background : linear-gradient(135deg, #f8f9fa, #e9ecef);
    border-left : 4px solid #6c757d;
    padding : 20px 25px;
    margin : 25px 0;
    border-radius : 0 12px 12px 0;
    font-style : italic;
  }
  .pg-quote-author {
    margin-top : 10px;
    font-size : 0.9em;
    color : #6c757d;
    font-style : normal;
  }
  .pg-tags {
    display : flex;
    flex-wrap : wrap;
    gap : 8px;
    margin-top : 30px;
  }
  .pg-tag {
    background : linear-gradient(135deg, #e9ecef, #f8f9fa);
    padding : 6px 14px;
    border-radius : 20px;
    font-size : 0.9em;
    color : #495057;
    border : 1px solid #dee2e6;
  }
  .pg-timeline {
    position : relative;
    padding-left : 35px;
    margin : 20px 0;
  }
  .pg-timeline::before {
    content : '';
    position : absolute;
    left : 10px;
    top : 0;
    bottom : 0;
    width : 3px;
    background : linear-gradient(to bottom, #28a745, #ffc107, #dc3545);
    border-radius : 3px;
  }
  .pg-timeline-item {
    position : relative;
    padding : 12px 0;
  }
  .pg-timeline-item::before {
    content : '';
    position : absolute;
    left : -31px;
    top : 16px;
    width : 14px;
    height : 14px;
    border-radius : 50%;
    background : white;
    border : 3px solid #007bff;
  }
  .pg-timeline-item.success::before { border-color : #28a745; }
  .pg-timeline-item.warning::before { border-color : #ffc107; }
  .pg-timeline-item.danger::before { border-color : #dc3545; }
  .pg-step-number {
    display : inline-flex;
    align-items : center;
    justify-content : center;
    width : 28px;
    height : 28px;
    background : linear-gradient(135deg, #007bff, #0056b3);
    color : white;
    border-radius : 50%;
    font-weight : 600;
    font-size : 0.9em;
    margin-right : 10px;
  }
&lt;/style&gt;
&lt;/div&gt;
&lt;article class=&quot;pg-article&quot;&gt;
&lt;p class=&quot;pg-subtitle&quot; data-ke-size=&quot;size16&quot;&gt;현기증 난단 말이에요... 분산 환경에서 살아남기 위한 처절한 기록&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQu24W/dJMcabbVoIF/CSF7yk4rkKAKkSDeGkDatK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQu24W/dJMcabbVoIF/CSF7yk4rkKAKkSDeGkDatK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQu24W/dJMcabbVoIF/CSF7yk4rkKAKkSDeGkDatK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQu24W%2FdJMcabbVoIF%2FCSF7yk4rkKAKkSDeGkDatK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;intro&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;&quot;서버가 죽었습니다&quot;&lt;/b&gt;라는 알림이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 최근 이 경험을 &lt;b&gt;두 번&lt;/b&gt;이나 했다. 그것도 같은 목적을 위해 다른 기술을 사용하다가. PostgreSQL의 논리복제(Logical Replication)로 한 번, FDW(Foreign Data Wrapper)로 또 한 번. 같은 실수를 두 번 하면 그건 실수가 아니라 실력이라던데... 그래, 인정한다. 이건 내 실력이다.  &lt;/p&gt;
&lt;div class=&quot;pg-card pg-card-danger&quot;&gt;
&lt;div style=&quot;text-align: center; padding: 10px;&quot;&gt;
&lt;p style=&quot;font-size: 1.15em; margin: 0; line-height: 2;&quot; data-ke-size=&quot;size16&quot;&gt; &amp;zwj;  &quot;어? 서버 왜 이렇게 느려요?&quot;&lt;br /&gt; &amp;zwj;  &quot;잠깐만... 뭐지?&quot;&lt;br /&gt; ️ &lt;code style=&quot;color: #dc3545; font-weight: bold; font-size: 1.1em;&quot;&gt;Connection refused&lt;/code&gt;&lt;br /&gt; &amp;zwj;  &quot;...&quot;&lt;br /&gt; &amp;zwj;  &quot;...&quot;&lt;br /&gt; &amp;zwj; &amp;zwj;  &lt;b&gt;&quot;현기증 난단 말이에요!!!&quot;&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 화려한 성공 스토리가 아니다. &lt;b&gt;처절한 실패와 현재 진행 중인 도전&lt;/b&gt;, 그리고 앞으로 어떻게 이 문제를 해결해 나갈 것인지에 대한 솔직한 기록이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 논리복제와 FDW에 대한 글을 썼었는데, 막상 실무에서 적용하다 보니 글로 정리한 것과 현실은 꽤나 달랐다. 블로그에 &quot;이렇게 하면 됩니다~&quot;라고 써놓고 정작 내가 그걸로 서버를 죽이다니. 아이러니하다.&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;div class=&quot;pg-card&quot;&gt;
&lt;h4 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size20&quot;&gt;  목차&lt;/h4&gt;
&lt;ul style=&quot;margin: 0; padding-left: 20px; line-height: 2;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#background&quot;&gt;프로젝트 배경 : 왜 실시간 동기화가 필요했나&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#architecture&quot;&gt;시스템 구성 : Tailscale VPN을 활용한 보안 연결&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#attempt1&quot;&gt;첫 번째 시도 : 논리복제(Logical Replication)의 배신&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#attempt2&quot;&gt;두 번째 시도 : FDW + 트리거, 되다가 갑자기 죽는 공포&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#incident&quot;&gt;사건의 전말 : 운영 서버가 죽기까지&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#analysis&quot;&gt;기술적 분석 : 도대체 왜 죽은 걸까&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#solution&quot;&gt;해결을 향한 여정 : 앞으로의 접근 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;마무리 : 실패도 자산이다&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;background&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 배경 : 왜 실시간 동기화가 필요했나&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;우리가 만들고 있는 것&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 진행 중인 솔루션은 &lt;b&gt;고객 사업장의 계측 데이터를 실시간으로 수집하여 중앙 서버에서 처리하고, 사용자에게 보여주는 시스템&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 IoT 데이터 수집 시스템이다. 공장이나 사업장에 설치된 각종 계측기(온도, 습도, 전력량 등)에서 데이터를 모아 중앙에서 모니터링하고 분석하는 것. 간단해 보이지만, 막상 구현하려니 온갖 문제가 터져 나왔다.&lt;/p&gt;
&lt;div class=&quot;pg-grid-2&quot;&gt;
&lt;div class=&quot;pg-info-box&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  사업장 A (Gathering PC x2)&lt;/h4&gt;
&lt;p style=&quot;margin: 0; color: #555;&quot; data-ke-size=&quot;size16&quot;&gt;수십 개의 계측기에서 1분 단위로 데이터 생성. 두 대의 게더링 PC가 각각 다른 구역의 계측기를 담당하고 있다. 한 대가 죽어도 다른 구역은 살아있어야 하니까.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-info-box&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  사업장 B (Gathering PC x1)&lt;/h4&gt;
&lt;p style=&quot;margin: 0; color: #555;&quot; data-ke-size=&quot;size16&quot;&gt;단일 접점에서 지속적인 트래픽 발생. 규모는 작지만 데이터 발생 빈도는 A 사업장과 비슷하다. 작다고 무시하면 안 된다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;시스템 규모와 요구사항&lt;/h3&gt;
&lt;table class=&quot;pg-table&quot; 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;체감 난이도&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;연결된 게더링 PC&lt;/td&gt;
&lt;td&gt;3대 (사업장 A : 2대, 사업장 B : 1대)&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;총 계측기 수&lt;/td&gt;
&lt;td&gt;약 40~50개&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;데이터 생성 주기&lt;/td&gt;
&lt;td&gt;약 1분마다 (계측기당)&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;일일 예상 데이터량&lt;/td&gt;
&lt;td&gt;약 60,000~70,000건/일&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background: #fff3cd;&quot;&gt;
&lt;td&gt;&lt;b&gt;핵심 요구사항&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;실시간성 확보 (지연 1분 이내)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;⭐⭐⭐⭐⭐ (지옥)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 &quot;3대 PC 연결&quot;이라고 하면 쉬워 보이지만, 각 PC에 연결된 수십 개의 계측기가 1분마다 데이터를 쏟아내고, 이걸 &lt;b&gt;실시간으로 중앙 서버에 전송&lt;/b&gt;해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &quot;실시간&quot;이라는 단어가 모든 재앙의 시작이었다. 고객은 &quot;실시간으로 보고 싶어요&quot;라고 했고, 나는 &quot;네, 가능합니다&quot;라고 대답했다. 그때의 나를 때리고 싶다.&lt;/p&gt;
&lt;div class=&quot;pg-quote&quot;&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;실시간이요? 그냥 DB 복제하면 되는 거 아니에요?&quot;&lt;/p&gt;
&lt;p class=&quot;pg-quote-author&quot; data-ke-size=&quot;size16&quot;&gt;&amp;mdash; 과거의 순진했던 나 (지금 생각하면 눈물이 난다)&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;architecture&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시스템 구성 : Tailscale VPN을 활용한 보안 연결&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;왜 VPN을 사용했나&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사업장의 게더링 PC에서 중앙 서버 DB로 직접 연결하려면 공인 IP가 필요하다. 하지만 보안상 DB 포트(5432)를 인터넷에 직접 노출시키는 건... 음, 그건 좀 아니지 않나?&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;PostgreSQL 포트를 공개 인터넷에 열어두는 건 해커들에게 &quot;어서 오세요, 환영합니다. 비밀번호는 postgres입니다&quot; 하는 것과 다를 바 없다. (설마 아직도 기본 비밀번호 쓰는 분은 없겠지...?)&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;Tailscale VPN&lt;/b&gt;이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Tailscale을 선택한 이유&lt;/h3&gt;
&lt;div class=&quot;pg-card pg-card-info&quot;&gt;
&lt;ul class=&quot;pg-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #28a745;&quot; class=&quot;pg-list-icon&quot;&gt;✓&lt;/span&gt;
&lt;div&gt;&lt;b&gt;Zero-config VPN:&lt;/b&gt; 복잡한 설정 없이 쉽게 구축 가능. OpenVPN처럼 인증서 관리하고 config 파일 만들고 할 필요 없다. 설치하고 로그인하면 끝.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #28a745;&quot; class=&quot;pg-list-icon&quot;&gt;✓&lt;/span&gt;
&lt;div&gt;&lt;b&gt;WireGuard 기반:&lt;/b&gt; 빠르고 안정적인 연결. IPSec보다 코드베이스가 작아서 보안 취약점도 적다. 레이턴시도 낮은 편.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #28a745;&quot; class=&quot;pg-list-icon&quot;&gt;✓&lt;/span&gt;
&lt;div&gt;&lt;b&gt;NAT 통과:&lt;/b&gt; 사업장 네트워크 환경이 복잡해도 연결 가능. 방화벽 뒤에서도 잘 동작한다. CGNAT도 뚫는다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #28a745;&quot; class=&quot;pg-list-icon&quot;&gt;✓&lt;/span&gt;
&lt;div&gt;&lt;b&gt;무료 플랜:&lt;/b&gt; 개인 사용자는 100대까지 무료. 우리처럼 소규모 구성에서는 무료로 충분하다. 이게 제일 중요하다  &lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전체 네트워크 구성도&lt;/h3&gt;
&lt;pre class=&quot;pg-diagram routeros&quot;&gt;&lt;code&gt;                         [ 인터넷 ]
                              │
             ┌────────────────┴────────────────┐
             │                                 │
             ▼                                 ▼
    ┌─────────────────┐              ┌─────────────────┐
    │   사업장 A       │              │   사업장 B       │
    │   (NAT 환경)    │              │   (NAT 환경)    │
    │                 │              │                 │
    │ ┌─────────────┐ │              │ ┌─────────────┐ │
    │ │게더링 PC 1  │ │              │ │게더링 PC 1  │ │
    │ │ Tailscale   │ │              │ │ Tailscale   │ │
    │ │ 100.x.x.10  │ │              │ │ 100.x.x.30  │ │
    │ │ PostgreSQL  │ │              │ │ PostgreSQL  │ │
    │ └─────────────┘ │              │ └─────────────┘ │
    │ ┌─────────────┐ │              └─────────────────┘
    │ │게더링 PC 2  │ │
    │ │ Tailscale   │ │      Tailscale Mesh Network
    │ │ 100.x.x.20  │ │     ━━━━━━━━━━━━━━━━━━━━━━━
    │ │ PostgreSQL  │ │               │
    │ └─────────────┘ │               │
    └─────────────────┘               │
                                      ▼
                            ┌─────────────────┐
                            │   중앙 서버      │
                            │   Tailscale      │
                            │   100.x.x.1     │
                            │                 │
                            │  ┌───────────┐  │
                            │  │PostgreSQL │  │
                            │  │   :5432   │  │
                            │  └───────────┘  │
                            └─────────────────┘

※ 공인 IP 노출 없이 Tailscale 내부 IP(100.x.x.x)로 안전하게 연결
※ 각 게더링 PC에 로컬 PostgreSQL 설치 (데이터 1차 저장)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구성하면 공인 IP 없이도 안전하게 DB에 접근할 수 있다. Tailscale 덕분에 마치 같은 사설 네트워크에 있는 것처럼 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 걱정은 덜었다. Tailscale은 믿을 만하다. 문제는... &lt;b&gt;보안이 아니라 완전히 다른 곳에서 터졌다.&lt;/b&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;attempt1&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;첫 번째 시도 : 논리복제(Logical Replication)의 배신&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;왜 논리복제를 선택했나&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PostgreSQL의 &lt;b&gt;논리복제(Logical Replication)&lt;/b&gt;는 PostgreSQL 10부터 도입된 기능으로, 물리복제와 달리 테이블 단위로 선택적 복제가 가능하다. 전체 DB를 복제할 필요 없이 필요한 테이블만 골라서 복제할 수 있다는 점이 매력적이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 Publisher-Subscriber 모델이라 직관적이다. 로컬 DB가 Publisher가 되어 데이터를 발행하고, 중앙 서버가 Subscriber가 되어 구독하면 끝. 심플하지 않은가?&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;br /&gt;  &lt;a href=&quot;https://odinbox.co.kr/555&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;PostgreSQL 논리복제 실무 가이드&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;논리복제의 기본 구조&lt;/h3&gt;
&lt;pre class=&quot;pg-code makefile&quot;&gt;&lt;code&gt;-- [로컬 게더링 PC] postgresql.conf 설정
-- 이것부터 해야 논리복제가 가능하다
wal_level = logical
max_replication_slots = 4
max_wal_senders = 4

-- 설정 변경 후 PostgreSQL 재시작 필수!
-- sudo systemctl restart postgresql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- [로컬 게더링 PC] Publication 생성
CREATE PUBLICATION measurement_pub 
FOR TABLE measurement_data, sensor_log;

-- 복제용 사용자 생성 (REPLICATION 권한 필요)
CREATE USER repl_user WITH REPLICATION PASSWORD 'secure_password';
GRANT SELECT ON measurement_data, sensor_log TO repl_user;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- [중앙 서버] Subscription 생성
-- Tailscale IP(100.x.x.10)로 연결
CREATE SUBSCRIPTION measurement_sub
CONNECTION 'host=100.x.x.10 port=5432 dbname=gathering user=repl_user password=secure_password'
PUBLICATION measurement_pub;

-- 이론상 이렇게 하면 끝...
-- 로컬에 INSERT하면 자동으로 서버에도 INSERT된다
-- 완벽하다! ...이론상은...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;처음 며칠은 잘 됐다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정하고 테스트해보니 진짜 잘 됐다. 로컬 DB에 데이터 넣으면 몇 초 안에 서버에서도 보인다. &quot;오 이거 되는데?&quot; 싶었다. 퇴근길 발걸음이 가벼웠다.&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;div class=&quot;pg-alert pg-alert-danger&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;⚠️ 결과 : 운영 서버 DB 다운&lt;/h4&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;어느 날 아침, 서버가 점점 느려지더니 결국 DB가 완전히 멈춰버렸다. 다른 서비스들도 같은 DB를 쓰고 있었는데, 전부 먹통이 됐다. 출근하자마자 전화가 빗발쳤다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;논리복제의 함정들&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;1&lt;/span&gt;복제 슬롯(Replication Slot)의 저주&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리복제는 &lt;code&gt;replication slot&lt;/code&gt;이라는 것을 사용한다. 이게 뭐냐면, Subscriber가 어디까지 데이터를 받았는지 추적하는 북마크 같은 거다.&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;문제는 Subscriber가 오프라인 상태가 되면 Publisher가 &quot;언젠간 얘가 돌아오겠지&quot;라며 &lt;b&gt;WAL(Write-Ahead Log) 로그를 무한정 보관&lt;/b&gt;한다는 것이다. Subscriber가 다시 연결되면 그동안 쌓인 변경사항을 보내줘야 하니까.&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;근데 사업장 네트워크가 불안정하거나, 게더링 PC가 재부팅되거나, VPN 연결이 끊어지면? Subscriber는 오프라인이 되고, WAL 로그는 계속 쌓인다. 하루, 이틀, 사흘... 디스크가 꽉 차면? &lt;b&gt;DB 사망.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 복제 슬롯 상태 확인
-- 이걸 자주 확인했어야 했다...  
SELECT slot_name, 
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal,
       active
FROM pg_replication_slots;

-- 실제로 내가 본 결과:
-- slot_name       | retained_wal | active
-- ----------------+--------------+--------
-- measurement_sub | 47 GB        | f
--
-- active가 'f'(false)인데 47GB나 쌓여있었다...
-- 서버 디스크 용량이 100GB였는데 절반을 WAL이 먹고 있었던 것
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;2&lt;/span&gt;초기 동기화(Initial Sync)의 공포&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Subscription을 생성하면 기본적으로 &lt;code&gt;copy_data = true&lt;/code&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;테스트 환경에서는 데이터가 몇 건 없어서 금방 끝났는데, 운영 환경에서 100만 건 있는 테이블에 이걸 했다가는... 복사하느라 CPU 100%, 네트워크 포화, 다른 쿼리는 전부 대기. 경험담이다.&lt;/p&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 초기 데이터 복사 없이 Subscription 생성하려면
CREATE SUBSCRIPTION measurement_sub
CONNECTION '...'
PUBLICATION measurement_pub
WITH (copy_data = false);  -- 기존 데이터 복사 안 함

-- 단, 이러면 구독 시작 시점 이후의 데이터만 복제됨
-- 기존 데이터는 별도로 마이그레이션 필요
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;3&lt;/span&gt;충돌 해결 메커니즘의 부재&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리복제는 기본적으로 &lt;b&gt;충돌 해결 메커니즘이 없다&lt;/b&gt;. 예를 들어, 같은 Primary Key로 데이터가 양쪽에 INSERT되면? 에러 나고 복제가 &lt;b&gt;완전히 멈춘다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동 복구? 그런 거 없다. 사람이 직접 충돌 해결하고, 복제 다시 시작해줘야 한다. 그것도 새벽에 서버 죽으면 새벽에 해야 한다.&lt;/p&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 에러 로그에서 자주 보게 될 메시지
ERROR : duplicate key value violates unique constraint &quot;measurement_data_pkey&quot;
DETAIL : Key (id)=(12345) already exists.
CONTEXT : processing remote data for replication origin &quot;pg_16389&quot; during &quot;INSERT&quot;

-- 이 에러 보면 복제가 멈춘 거다
-- 복제 상태 확인
SELECT * FROM pg_stat_subscription;

-- last_msg_receipt_time이 안 바뀌면 복제가 멈춘 것
-- 야근 확정  
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg-quote&quot;&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;논리복제 쓰면 실시간 동기화 쉽게 되지 않아요?&quot;&lt;/p&gt;
&lt;p class=&quot;pg-quote-author&quot; data-ke-size=&quot;size16&quot;&gt;&amp;mdash; 과거의 나. 지금 보면 참 순진했다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;attempt2&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;두 번째 시도 : FDW + 트리거, 되다가 갑자기 죽는 공포&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;논리복제가 안 되면 FDW다!&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리복제의 처참한 실패 후, 좀 더 제어 가능한 방식을 찾았다. PostgreSQL의 &lt;b&gt;FDW(Foreign Data Wrapper)&lt;/b&gt;는 Oracle의 DB Link와 비슷한 개념으로, 외부 데이터베이스를 마치 로컬 테이블처럼 접근할 수 있게 해준다.&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;Oracle에서 &lt;code&gt;SELECT * FROM remote_table@dblink&lt;/code&gt; 하는 것처럼, PostgreSQL에서도 외부 DB의 테이블을 로컬처럼 쓸 수 있다. 이전에 정리해둔 글이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;  &lt;a href=&quot;https://odinbox.co.kr/568&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;PostgreSQL FDW(Foreign Data Wrapper) 사용법&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;FDW vs Oracle DB Link 비교&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oracle DB Link 쓰다가 PostgreSQL로 넘어온 분들을 위해 비교표를 만들어봤다.&lt;/p&gt;
&lt;table class=&quot;pg-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;PostgreSQL FDW&lt;/th&gt;
&lt;th&gt;Oracle DB Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;설치 방법&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE EXTENSION postgres_fdw&lt;/code&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;FOREIGN TABLE 생성 필요&lt;/td&gt;
&lt;td&gt;&lt;code&gt;테이블명@링크명&lt;/code&gt;으로 바로 접근&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;분산 트랜잭션 (2PC)&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;지원 (WHERE 절 등 원격 실행)&lt;/td&gt;
&lt;td&gt;제한적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;설정 복잡도&lt;/td&gt;
&lt;td&gt;SERVER &amp;rarr; USER MAPPING &amp;rarr; FOREIGN TABLE 순서&lt;/td&gt;
&lt;td&gt;CREATE DATABASE LINK 한 줄&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;h3 data-ke-size=&quot;size23&quot;&gt;FDW + 트리거 조합 아이디어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디어는 이랬다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;로컬 DB에 데이터가 INSERT되면&lt;/li&gt;
&lt;li&gt;AFTER INSERT 트리거 발동&lt;/li&gt;
&lt;li&gt;트리거 함수에서 FDW를 통해 서버 DB에 즉시 전송&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간성 완벽!&lt;/b&gt; 데이터가 들어오는 즉시 서버로 전송되니까. ...라고 생각했다.&lt;/p&gt;
&lt;pre class=&quot;pg-code routeros&quot;&gt;&lt;code&gt;-- 1. FDW 확장 설치
CREATE EXTENSION postgres_fdw;

-- 2. 외부 서버 정의 (Tailscale IP 사용)
CREATE SERVER central_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '100.x.x.1', dbname 'production', port '5432');

-- 3. 사용자 매핑 (로컬 사용자 &amp;rarr; 원격 사용자)
CREATE USER MAPPING FOR local_user
SERVER central_server
OPTIONS (user 'sync_user', password '********');

-- 4. 외부 테이블 정의 (서버의 테이블을 로컬에서 접근)
CREATE FOREIGN TABLE remote_measurement (
    id BIGINT,
    sensor_id INTEGER,
    value NUMERIC(10,2),
    measured_at TIMESTAMP,
    created_at TIMESTAMP
) SERVER central_server
OPTIONS (schema_name 'public', table_name 'measurement_data');
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 5. 실시간 동기화 트리거 함수
CREATE OR REPLACE FUNCTION sync_to_server()
RETURNS TRIGGER AS $$
BEGIN
    -- 원격 테이블에 INSERT
    INSERT INTO remote_measurement (id, sensor_id, value, measured_at, created_at)
    VALUES (NEW.id, NEW.sensor_id, NEW.value, NEW.measured_at, NEW.created_at);
    
    RETURN NEW;
    
EXCEPTION WHEN OTHERS THEN
    -- 에러 발생해도 로컬 INSERT는 성공하도록
    RAISE WARNING 'Remote sync failed : %', SQLERRM;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 6. 트리거 생성
CREATE TRIGGER trg_sync_measurement
AFTER INSERT ON measurement_data
FOR EACH ROW
EXECUTE FUNCTION sync_to_server();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;처음에는 진짜 잘 됐다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트해보니 완벽했다. 로컬에 INSERT하면 바로 서버에서 보인다. 논리복제처럼 복잡한 설정도 없고, 복제 슬롯이니 WAL이니 신경 쓸 것도 없다. 트리거로 직접 밀어넣으니까.&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; 싶었다. 동료들한테 자랑도 했다. &quot;FDW로 실시간 동기화 구현했어요. 깔끔하죠?&quot; 그렇게 며칠이 지났다...&lt;/p&gt;
&lt;div class=&quot;pg-alert pg-alert-danger&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;⚠️ 결과 : 또 서버 다운&lt;/h4&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 잘 됐다. 정말 잘 됐다. 그런데 며칠 지나니까 &lt;b&gt;되다가 갑자기 죽고, 또 되다가 갑자기 죽고&lt;/b&gt;... 패턴도 없이 랜덤하게 죽었다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 더 미치는 거였다. 논리복제는 그래도 WAL 로그 쌓이는 거 보면서 &quot;아, 이거 위험하겠다&quot; 예측이라도 됐는데, FDW + 트리거 조합은 &lt;b&gt;아무런 전조 증상 없이 갑자기 죽었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어제까지 멀쩡했는데 오늘 갑자기 서버가 죽어있다. 왜? 모른다. 로그 봐도 뭔가 쌓이다가 갑자기 뻗은 것 같은데, 명확한 원인을 찾기 어려웠다.&lt;/p&gt;
&lt;div class=&quot;pg-grid-2&quot;&gt;
&lt;div class=&quot;pg-card&quot;&gt;
&lt;h4 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size20&quot;&gt;  장애 발생 패턴 (패턴이 없다)&lt;/h4&gt;
&lt;div style=&quot;font-family: monospace; line-height: 2.2;&quot;&gt;Day 1 : ✅ 정상 동작 - &quot;오 잘 되네!&quot;&lt;br /&gt;Day 2 : ✅ 정상 동작 - &quot;역시 FDW 짱&quot;&lt;br /&gt;Day 3 : ✅ 정상 동작 - &quot;이번엔 성공인가?&quot;&lt;br /&gt;Day 4 : ✅ 정상... 어라?&lt;br /&gt;Day 4 : ⚠️ 서버 점점 느려짐&lt;br /&gt;Day 4 : ❌ &lt;span style=&quot;color: #dc3545; font-weight: bold;&quot;&gt;서버 다운&lt;/span&gt;&lt;br /&gt;Day 5 : ✅ 복구 후 정상&lt;br /&gt;Day 6 : ✅ 정상&lt;br /&gt;Day 7 : ❌ &lt;span style=&quot;color: #dc3545; font-weight: bold;&quot;&gt;또 다운&lt;/span&gt; (왜?!)&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-gauge-container&quot;&gt;
&lt;div class=&quot;pg-gauge-title&quot;&gt;현재 나의 멘붕 지수&lt;/div&gt;
&lt;div class=&quot;pg-gauge-bar&quot;&gt;
&lt;div class=&quot;pg-gauge-fill&quot; style=&quot;width: 95%;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p class=&quot;pg-gauge-text&quot; data-ke-size=&quot;size16&quot;&gt;&quot;현기증 난단 말이에요...&quot;&lt;/p&gt;
&lt;p style=&quot;margin-top: 15px; font-size: 0.9em; color: #666;&quot; data-ke-size=&quot;size16&quot;&gt;논리복제로 한 번, FDW로 또 한 번...&lt;br /&gt;이쯤 되면 나한테 문제가 있는 거 아닌가?&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;incident&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사건의 전말 : 운영 서버가 죽기까지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그날의 상황을 복기해보자. 나중에 포스트모템(Post-mortem) 자료로도 쓸 수 있으니까. 사실 이 글 자체가 포스트모템이긴 하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;D-Day 타임라인&lt;/h3&gt;
&lt;div class=&quot;pg-card&quot;&gt;
&lt;div class=&quot;pg-timeline&quot;&gt;
&lt;div class=&quot;pg-timeline-item success&quot;&gt;&lt;b&gt;  14:00&lt;/b&gt; - 평화로운 오후. 커피 한 잔 하면서 다른 작업 중. 오늘따라 날씨도 좋고, 퇴근 후 뭐 먹을지 고민하던 중이었다. 인생 뭐 있나, 평온하다.&lt;/div&gt;
&lt;div class=&quot;pg-timeline-item warning&quot;&gt;&lt;b&gt;  14:23&lt;/b&gt; - 동료 : &lt;i&gt;&quot;어? 시스템 좀 느린 것 같지 않아요?&quot;&lt;/i&gt;&lt;br /&gt;나 : &lt;i&gt;&quot;그래요? 잠깐 볼게요.&quot;&lt;/i&gt; (이때까지만 해도 대수롭지 않게 생각함. 가끔 느릴 때 있으니까.)&lt;/div&gt;
&lt;div class=&quot;pg-timeline-item warning&quot;&gt;&lt;b&gt;  14:28&lt;/b&gt; - 서버 접속. 평소보다 확실히 느리다. 터미널 응답도 늦고, 쿼리도 오래 걸린다. 뭔가 심상치 않은 느낌...&lt;/div&gt;
&lt;div class=&quot;pg-timeline-item danger&quot;&gt;&lt;b&gt;  14:30&lt;/b&gt; - DB 상태 확인 시작. 여기서부터 식은땀이 나기 시작했다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 14:30 현재 실행 중인 쿼리 확인
SELECT pid, 
       now() - pg_stat_activity.query_start AS duration, 
       state,
       wait_event_type,
       left(query, 80) AS query_preview
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY duration DESC
LIMIT 10;

-- 결과 (대략적으로 재현):
-- pid   | duration  | state  | wait_event_type | query_preview
-- ------+-----------+--------+-----------------+---------------------------
-- 12345 | 00:12:34  | active | Client          | INSERT INTO remote_measurement...
-- 12346 | 00:11:22  | active | Client          | INSERT INTO remote_measurement...
-- 12347 | 00:10:15  | active | Client          | INSERT INTO remote_measurement...
-- ... (수십 개가 더 있었다)
--
-- wait_event_type이 'Client' &amp;rarr; 원격 서버 응답 대기 중
-- 10분 넘게 대기 중인 쿼리가 수십 개...  
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg-card&quot;&gt;
&lt;div class=&quot;pg-timeline&quot;&gt;
&lt;div class=&quot;pg-timeline-item danger&quot;&gt;&lt;b&gt;  14:35&lt;/b&gt; - 트리거 실행 상태 점검. FDW를 통한 원격 INSERT들이 타임아웃 없이 &lt;b&gt;무한 대기 상태&lt;/b&gt;. 트리거에 타임아웃 설정을 안 했던 것이다.&lt;/div&gt;
&lt;div class=&quot;pg-timeline-item danger&quot;&gt;&lt;b&gt;  14:38&lt;/b&gt; - 혹시나 해서 논리복제 상태도 확인. (이전에 테스트하다 남겨둔 게 있었다) 여기도 WAL이 수십 GB 쌓여있었다. 설상가상.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 14:42 커넥션 풀 상태 확인
SELECT 
    count(*) AS current_connections,
    (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections,
    round(count(*) * 100.0 / (SELECT setting::int FROM pg_settings WHERE name = 'max_connections'), 1) AS usage_pct
FROM pg_stat_activity;

-- 결과:
-- current_connections | max_connections | usage_pct
-- --------------------+-----------------+-----------
-- 198                 | 200             | 99.0
--
-- 거의 다 찼다! 새로운 연결이 거의 불가능한 상태
-- 이러니까 다른 서비스도 DB 연결이 안 됐던 것...
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg-card pg-card-danger&quot;&gt;
&lt;div class=&quot;pg-timeline&quot;&gt;
&lt;div class=&quot;pg-timeline-item danger&quot;&gt;&lt;b&gt;  14:45&lt;/b&gt; - 동료들 : &lt;i&gt;&quot;다른 서비스도 안 돼요! 로그인이 안 돼요! 뭐 하신 거예요?!&quot;&lt;/i&gt;&lt;br /&gt;나 : (식은땀 줄줄) &quot;아... 잠깐만요...&quot; 다른 서비스들도 같은 DB를 쓰고 있었는데, 커넥션이 다 차버려서 새 연결이 안 되는 거였다.&lt;/div&gt;
&lt;div class=&quot;pg-timeline-item danger&quot;&gt;&lt;b&gt;  14:50&lt;/b&gt; - &lt;b&gt;결단의 순간.&lt;/b&gt; 더 이상 분석하고 있을 시간이 없다. 일단 불부터 끄자.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 14:50 응급 처치 시작 (순서대로)

-- 1. 문제가 되는 트리거 즉시 비활성화
ALTER TABLE measurement_data DISABLE TRIGGER trg_sync_measurement;
-- 이제 새로운 INSERT는 원격 전송 시도 안 함

-- 2. 5분 이상 실행 중인 쿼리 강제 종료
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE now() - query_start &amp;gt; interval '5 minutes'
  AND state != 'idle'
  AND pid != pg_backend_pid();  -- 내 세션은 제외
-- 약 50개 세션 종료됨

-- 3. 복제 슬롯 삭제 (WAL 디스크 해방)
SELECT pg_drop_replication_slot(slot_name)
FROM pg_replication_slots
WHERE active = false;
-- 비활성 슬롯 삭제 &amp;rarr; 수십 GB WAL 해방

-- 4. 오래된 idle 커넥션 정리
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
  AND state_change &amp;lt; now() - interval '30 minutes';
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg-card pg-card-success&quot;&gt;
&lt;div class=&quot;pg-timeline&quot;&gt;
&lt;div class=&quot;pg-timeline-item success&quot;&gt;&lt;b&gt;  15:10&lt;/b&gt; - 서버 정상화. 커넥션 수 정상 범위로 돌아오고, 다른 서비스들도 복구됨.&lt;br /&gt;하지만 마음의 상처는 회복되지 않았다... 그리고 이제 원인 분석과 재발 방지 대책을 세워야 한다. 야근 확정.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-alert pg-alert-info&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  그날의 교훈&lt;/h4&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;트리거 문제, 논리복제 문제 다 겪어보니 식은땀과 정신이 혼미해지네...&quot;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&quot;현기증 난단 말이에요!!!&quot;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;진짜 현기증 났다. 비유가 아니라.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;analysis&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기술적 분석 : 도대체 왜 죽은 걸까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사건이 진정된 후, 원인을 철저히 분석했다. 야근하면서. 커피 다섯 잔 마시면서.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하면, 두 가지 방식 모두 &lt;b&gt;동기식 처리의 한계&lt;/b&gt;라는 같은 문제를 안고 있었다.&lt;/p&gt;
&lt;div class=&quot;pg-grid-2&quot;&gt;
&lt;div class=&quot;pg-card pg-card-orange&quot;&gt;
&lt;h4 style=&quot;margin: 0 0 20px 0;&quot; data-ke-size=&quot;size20&quot;&gt;⚡ FDW + Trigger의 한계&lt;/h4&gt;
&lt;ul class=&quot;pg-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;동기적 처리:&lt;/b&gt; 트리거 안에서 원격 쿼리 실행. 네트워크가 느려지면 SQL 실행 자체가 멈춘다. 원격 쿼리가 끝날 때까지 로컬 트랜잭션도 대기.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;VPN 오버헤드:&lt;/b&gt; Tailscale 암호화 터널을 지나는 매 쿼리마다 약간의 지연 발생. 쿼리 한두 개면 모르는데, 1분에 수십 개씩 쌓이면 누적된다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;트리거 락:&lt;/b&gt; AFTER INSERT 트리거가 끝날 때까지 해당 행에 Lock이 유지된다. 트리거가 느리면 다른 INSERT도 대기.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;커넥션 고갈:&lt;/b&gt; FDW는 원격 쿼리마다 커넥션을 사용한다. 동시에 여러 트리거가 실행되면 커넥션 풀이 순식간에 소진.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-purple&quot;&gt;
&lt;h4 style=&quot;margin: 0 0 20px 0;&quot; data-ke-size=&quot;size20&quot;&gt;  논리 복제의 함정&lt;/h4&gt;
&lt;ul class=&quot;pg-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;WAL 무한 증식:&lt;/b&gt; Subscriber가 오프라인이면 Publisher의 WAL 로그가 계속 쌓인다. 디스크 풀 &amp;rarr; DB 사망 루트.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;스키마 민감도:&lt;/b&gt; Publisher와 Subscriber의 테이블 구조가 조금만 달라도 복제 중단. 컬럼 추가하려면 양쪽 다 해야 한다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;충돌 미해결:&lt;/b&gt; PK 충돌 시 복제가 완전히 멈춘다. 자동 해결 없음. 사람이 직접 해결해야 함.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dc3545;&quot; class=&quot;pg-list-icon&quot;&gt;✗&lt;/span&gt;
&lt;div&gt;&lt;b&gt;리소스 경합:&lt;/b&gt; 복제 프로세스(wal sender, logical replication worker)가 CPU와 I/O를 꽤 잡아먹는다.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 문제 : 동기식 처리의 한계&lt;/h3&gt;
&lt;div class=&quot;pg-alert pg-alert-info&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  핵심 깨달음&lt;/h4&gt;
&lt;p style=&quot;margin: 0; font-size: 1.05em;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;원격 작업이 로컬 작업을 블로킹하면 안 된다!&quot;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;실시간이라고 해서 반드시 동기식으로 처리할 필요는 없다. 서버에 문제가 생겨도 &lt;b&gt;로컬 시스템은 정상 동작&lt;/b&gt;해야 한다. 이게 분산 시스템의 기본 원칙인데, 나는 이걸 망각했다.&lt;/p&gt;
&lt;/div&gt;
&lt;pre class=&quot;pg-diagram css&quot;&gt;&lt;code&gt;/* 문제의 흐름 - 동기식 처리의 위험 */

[계측기] &amp;rarr; [로컬 DB INSERT] &amp;rarr; [트리거 발동] &amp;rarr; [FDW 원격 INSERT]
                                                            │
                                                            ▼
                                                    네트워크 지연 발생!
                                                            │
                                                            ▼
                                          로컬 트랜잭션도 대기 상태로 전환
                                                            │
                                                            ▼
                                              다음 INSERT도 대기열에 쌓임
                                                            │
                                                            ▼
                                           커넥션 풀 고갈 &amp;rarr; DB 다운

핵심 : 원격 장애가 로컬 시스템 전체를 멈추게 하면 안 된다!
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사업장의 인터넷이 느려지거나, 중앙 서버가 잠깐 바빠지거나, VPN이 불안정해지면 그 영향이 로컬 시스템까지 전파되는 구조였다. 이건 설계 자체가 잘못된 것이다.&lt;/p&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;solution&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결을 향한 여정 : 앞으로의 접근 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 고백하면, 아직 완벽한 해결책을 찾지 못했다. 하지만 여러 가지 방법을 조사하고 테스트하면서, 앞으로 이런 방향으로 접근하려고 한다.&lt;/p&gt;
&lt;div class=&quot;pg-alert pg-alert-success&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  핵심 원칙&lt;/h4&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;로컬 작업과 원격 동기화를 분리하자&quot;&lt;/b&gt;&lt;br /&gt;원격 서버에 문제가 생겨도 로컬 시스템은 정상 동작해야 한다. 이게 이번 삽질에서 얻은 가장 큰 교훈이다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-success&quot;&gt;
&lt;h3 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;1&lt;/span&gt;'동기'에서 '비동기'로의 전환&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리거에서 즉시 원격 서버로 쏘지 말고, &lt;b&gt;로컬에 임시 테이블(큐)을 두거나 메시지 큐(MQTT, RabbitMQ)를 사용&lt;/b&gt;해 서버가 한가할 때 가져가게 하는 방식이 안전하다.&lt;/p&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 동기화 큐 테이블 생성
CREATE TABLE sync_queue (
    id BIGSERIAL PRIMARY KEY,
    table_name VARCHAR(100) NOT NULL,
    record_id BIGINT NOT NULL,
    operation VARCHAR(10) NOT NULL,
    payload JSONB NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    retry_count INTEGER DEFAULT 0,
    last_error TEXT,
    status VARCHAR(20) DEFAULT 'pending'
);

CREATE INDEX idx_sync_queue_status ON sync_queue(status, created_at);

-- 트리거는 큐에 넣기만 한다 (매우 빠름!)
CREATE OR REPLACE FUNCTION queue_for_sync()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO sync_queue (table_name, record_id, operation, payload)
    VALUES (TG_TABLE_NAME, NEW.id, TG_OP, row_to_json(NEW)::jsonb);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 로컬 INSERT는 로컬 테이블에 한 줄 추가하는 것으로 끝난다. 밀리초 단위로 끝난다. 원격 서버가 죽어있든 말든 상관없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별도의 워커 프로세스가 주기적으로 큐를 확인하고 서버로 전송한다. 실패하면 retry_count 올리고 나중에 다시 시도.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-info&quot;&gt;
&lt;h3 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;2&lt;/span&gt;배치(Batch) 인서트 활용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 1분에 수십 개씩 발생한다면, 건건이 쏘지 말고 &lt;b&gt;5분치 데이터를 모아서 한 번에 서버로 COPY 명령어&lt;/b&gt;를 날리는 것이 훨씬 효율적이다.&lt;/p&gt;
&lt;pre class=&quot;pg-code sql&quot;&gt;&lt;code&gt;-- PostgreSQL COPY는 대량 INSERT보다 훨씬 빠름
-- 100건 INSERT하는 것보다 COPY로 100건 넣는 게 10배는 빠르다

-- 방법 1 : CSV 파일로 내보내고 COPY
COPY (
    SELECT id, sensor_id, value, measured_at 
    FROM sync_queue 
    WHERE status = 'pending'
    LIMIT 1000
) TO '/tmp/batch_data.csv' WITH CSV;

-- 방법 2 : INSERT ... SELECT로 배치 처리 (FDW 사용)
INSERT INTO remote_measurement (id, sensor_id, value, measured_at)
SELECT (payload-&amp;gt;&amp;gt;'id')::bigint,
       (payload-&amp;gt;&amp;gt;'sensor_id')::int,
       (payload-&amp;gt;&amp;gt;'value')::numeric,
       (payload-&amp;gt;&amp;gt;'measured_at')::timestamp
FROM sync_queue 
WHERE status = 'pending'
LIMIT 500;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 왕복 횟수가 대폭 줄어든다. 100번 왕복할 거 1번으로 끝. 서버 부하도 분산된다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-purple&quot;&gt;
&lt;h3 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;3&lt;/span&gt;헬스 체크 및 모니터링 강화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 느려질 때 바로 알 수 있도록 &lt;b&gt;모니터링 시스템&lt;/b&gt;을 구축해야 한다. 문제가 터지기 전에 감지하는 게 최선이다.&lt;/p&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 모니터링 필수 쿼리들 (크론으로 1분마다 실행)

-- 1. 복제 슬롯 WAL 누적량 (1GB 이상이면 경고)
SELECT slot_name,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal,
       active,
       CASE 
           WHEN pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) &amp;gt; 1073741824 
           THEN '⚠️ WARNING'
           ELSE '✅ OK'
       END AS status
FROM pg_replication_slots;

-- 2. 커넥션 사용량 (80% 이상이면 경고)
SELECT 
    count(*) AS current_conn,
    (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_conn,
    round(count(*) * 100.0 / (SELECT setting::int FROM pg_settings WHERE name = 'max_connections'), 1) AS pct
FROM pg_stat_activity;

-- 3. 장시간 실행 쿼리 (5분 이상이면 경고)
SELECT count(*) AS long_running_queries
FROM pg_stat_activity
WHERE state != 'idle' 
  AND now() - query_start &amp;gt; interval '5 minutes';
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prometheus + Grafana 조합이 좋다. postgres_exporter를 붙이면 PostgreSQL 메트릭을 자동으로 수집해준다. 대시보드도 이쁘게 만들 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-teal&quot;&gt;
&lt;h3 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;4&lt;/span&gt;CDC(Change Data Capture) 검토&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Debezium&lt;/b&gt; 같은 CDC 도구를 사용하면 PostgreSQL의 WAL 로그를 직접 읽어서 변경 이벤트를 발행할 수 있다. 논리복제보다 더 유연하고, 트리거보다 안전하다.&lt;/p&gt;
&lt;pre class=&quot;pg-diagram less&quot;&gt;&lt;code&gt;/* CDC 기반 아키텍처 */

[PostgreSQL] ──WAL──▶ [Debezium] ──▶ [Kafka] ──▶ [Consumer] ──▶ [서버 DB]
      │                      │
      │                      └── 변경 이벤트를 JSON으로 발행
      │
      └── 애플리케이션 코드 수정 불필요!
           기존 INSERT/UPDATE/DELETE 그대로 사용
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점은 애플리케이션 코드를 전혀 수정하지 않아도 된다는 것. 단점은 인프라가 복잡해진다는 것. Debezium + Kafka + ZooKeeper... 소규모에는 오버스펙일 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-warning&quot;&gt;
&lt;h3 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;5&lt;/span&gt;하이브리드 전략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 데이터를 똑같이 처리할 필요는 없다. &lt;b&gt;데이터 특성에 따라 다른 전략&lt;/b&gt;을 사용하는 것이 현실적이다.&lt;/p&gt;
&lt;pre class=&quot;pg-diagram angelscript&quot;&gt;&lt;code&gt;/* 하이브리드 전략 */

[긴급 알람 데이터] &amp;larr; 온도 이상, 장비 고장 등
  └── REST API 직접 전송 (동기, 하지만 타임아웃 설정)
  └── 실패 시 로컬 큐에 저장 후 재시도
  └── 지연 허용 : 0~5초

[일반 계측 데이터] &amp;larr; 1분마다 쌓이는 센서 데이터
  └── 로컬 DB에 저장
  └── 5분마다 배치로 서버 전송
  └── 지연 허용 : ~5분

[이력/로그 데이터] &amp;larr; 기기 로그, 작업 이력 등
  └── 1시간마다 또는 하루에 한 번 동기화
  └── 실시간성 불필요
  └── 지연 허용 : ~24시간

핵심 질문 : 정말 모든 데이터에 &quot;실시간&quot;이 필요한가?  
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객한테 다시 물어봐야 한다. &quot;정말 모든 데이터가 실시간으로 필요하신 건가요? 아니면 알람만 실시간이면 되나요?&quot; 요구사항을 다시 정의하는 것도 방법이다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-card pg-card-orange&quot;&gt;
&lt;h3 style=&quot;margin: 0 0 15px 0;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg-step-number&quot;&gt;6&lt;/span&gt;FDW 개선 (당장 적용 가능)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당장 구조를 바꾸기 어렵다면, 최소한 &lt;b&gt;타임아웃 설정과 예외 처리 강화&lt;/b&gt;는 해야 한다. 이건 오늘이라도 할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;pg-code routeros&quot;&gt;&lt;code&gt;-- FDW 연결에 타임아웃 설정 (필수!)
ALTER SERVER central_server OPTIONS (
    ADD connect_timeout '10',
    ADD options '-c statement_timeout=30000'
);

-- connect_timeout : 연결 타임아웃 10초
-- statement_timeout : 쿼리 타임아웃 30초 (30000ms)
-- 이 설정 없으면 무한 대기할 수 있다!
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pg-code pgsql&quot;&gt;&lt;code&gt;-- 트리거에서 예외 처리 강화 + 실패 로깅
CREATE OR REPLACE FUNCTION sync_to_server_safe()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO remote_measurement (id, sensor_id, value, measured_at)
    VALUES (NEW.id, NEW.sensor_id, NEW.value, NEW.measured_at);
    
    RETURN NEW;
    
EXCEPTION WHEN OTHERS THEN
    -- 실패해도 로컬 INSERT는 성공하도록!
    INSERT INTO sync_failure_log (
        table_name, record_id, error_message, created_at
    ) VALUES (
        'measurement_data', NEW.id, SQLERRM, NOW()
    );
    
    RETURN NEW;  -- 에러 나도 RETURN NEW!
END;
$$ LANGUAGE plpgsql;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  단계별 실행 계획&lt;/h3&gt;
&lt;table class=&quot;pg-table&quot; 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;예상 기간&lt;/th&gt;
&lt;th&gt;우선순위&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;즉시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;FDW 타임아웃 설정 + 예외 처리 강화 + 모니터링 쿼리 작성&lt;/td&gt;
&lt;td&gt;1주&lt;/td&gt;
&lt;td style=&quot;color: #dc3545;&quot;&gt;  긴급&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;단기&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;sync_queue 테이블 도입 + 워커 프로세스 개발&lt;/td&gt;
&lt;td&gt;2-3주&lt;/td&gt;
&lt;td style=&quot;color: #fd7e14;&quot;&gt;  높음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;중기&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;RabbitMQ 또는 MQTT 도입 검토 및 테스트&lt;/td&gt;
&lt;td&gt;1-2개월&lt;/td&gt;
&lt;td style=&quot;color: #ffc107;&quot;&gt;  중간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;장기&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;데이터 특성별 하이브리드 전략 완성 + CDC 검토&lt;/td&gt;
&lt;td&gt;3개월+&lt;/td&gt;
&lt;td style=&quot;color: #28a745;&quot;&gt;  개선&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;pg-alert pg-alert-success&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  현재 상태&lt;/h4&gt;
&lt;p style=&quot;margin: 0;&quot; data-ke-size=&quot;size16&quot;&gt;솔직히 말하면, 여러 가지 방법을 시도 중이고 아직도 삽질하는 중이다. 하지만 &lt;b&gt;반드시 성공할 것이다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;이 문제를 해결하면 다시 성공 사례를 공유하겠다. 그때는 &quot;이렇게 하면 됩니다~&quot;라고 자신 있게 말할 수 있을 거다. 아마도.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section id=&quot;conclusion&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리 : 실패도 자산이다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기술 블로그에는 보통 성공 사례만 올라온다. &lt;i&gt;&quot;이렇게 하면 됩니다&quot;&lt;/i&gt;, &lt;i&gt;&quot;이 방법으로 해결했습니다&quot;&lt;/i&gt; 같은 글들이 대부분이다. 나도 그런 글을 썼었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 현실에서는 실패가 훨씬 많다. 10번 시도해서 1번 성공하면 그나마 다행이다. 나머지 9번의 실패는 어디로 갔을까? 블로그에는 안 올라온다. 부끄러우니까.&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;다른 개발자들이 같은 실수를 반복하지 않도록 도움&lt;/li&gt;
&lt;li&gt;&quot;나만 이런 거 아니구나&quot;라는 위안 제공&lt;/li&gt;
&lt;li&gt;글로 정리하면서 스스로 원인과 해결책을 명확히 정리&lt;/li&gt;
&lt;li&gt;나중에 비슷한 상황에서 참고 자료로 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;pg-card&quot;&gt;
&lt;h4 style=&quot;margin: 0 0 20px 0;&quot; data-ke-size=&quot;size20&quot;&gt;  이 글의 핵심 요약&lt;/h4&gt;
&lt;ol style=&quot;margin: 0; padding-left: 25px; line-height: 2.2;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;논리복제&lt;/b&gt; : 강력하지만 복제 슬롯 관리 실패하면 WAL이 쌓여서 서버가 죽는다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;FDW + 트리거&lt;/b&gt; : 편리하지만 타임아웃 없으면 되다가 갑자기 죽는다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tailscale VPN&lt;/b&gt; : 보안 연결은 완벽했다. 문제는 그 위의 레이어(DB 동기화)였다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동기식 처리의 한계&lt;/b&gt; : 원격 장애가 로컬 시스템에 영향 주면 안 된다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비동기 방식&lt;/b&gt; : 메시지 큐, CDC, 애플리케이션 큐 등 대안이 많다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모니터링&lt;/b&gt; : 문제가 터지기 전에 감지하는 게 최선이다&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;pg-quote&quot;&gt;
&lt;p style=&quot;margin: 0; font-size: 1.1em;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;실패는 성공의 어머니다. 단, 같은 실패를 반복하지 않을 때만.&quot;&lt;/p&gt;
&lt;p class=&quot;pg-quote-author&quot; data-ke-size=&quot;size16&quot;&gt;&amp;mdash; 서버 두 번 죽여본 개발자의 교훈&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글을 읽는 누군가가 비슷한 상황에서 조금이라도 도움이 되었으면 좋겠다. 그리고 제발, 나처럼 서버를 두 번 죽이진 말자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 이 문제를 해결하면 그때 다시 성공 사례를 공유하겠다. 그때까지는... 삽질 일지를 계속 써나가야겠다. 화이팅.  &lt;/p&gt;
&lt;div class=&quot;pg-card pg-card-warning&quot; style=&quot;text-align: center;&quot;&gt;
&lt;p style=&quot;margin: 0; font-size: 1.15em; line-height: 2;&quot; data-ke-size=&quot;size16&quot;&gt; &amp;zwj;  트리거 문제, 논리복제 문제 다 겪어보니&lt;br /&gt;식은땀과 정신이 혼미해지네...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&quot;현기증 난단 말이에요!!!&quot;&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;관련 포스팅&lt;/h3&gt;
&lt;ul style=&quot;line-height: 2;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://odinbox.co.kr/555&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;PostgreSQL 논리복제 실무 가이드&lt;/a&gt; - 논리복제 설정 방법 (이론편)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://odinbox.co.kr/568&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;PostgreSQL FDW(Foreign Data Wrapper) 사용법&lt;/a&gt; - FDW 기본 사용법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;궁금한 점이나 비슷한 경험이 있다면 댓글로 공유 부탁드립니다. 함께 고민하면 더 좋은 해결책을 찾을 수 있을 것입니다.  &lt;/p&gt;
&lt;/section&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;section&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Tags&lt;/h3&gt;
&lt;div class=&quot;pg-tags&quot;&gt;&lt;span class=&quot;pg-tag&quot;&gt;#PostgreSQL&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#논리복제&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#LogicalReplication&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#FDW&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#실시간데이터동기화&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#TailscaleVPN&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#분산데이터베이스&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#데이터베이스장애&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#개발삽질기&lt;/span&gt; &lt;span class=&quot;pg-tag&quot;&gt;#IoT데이터수집&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;/article&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;script type=&quot;application/ld+json&quot;&gt;
{&quot;@context&quot;:&quot;https://schema.org&quot;,&quot;@type&quot;:&quot;TechArticle&quot;,&quot;headline&quot;:&quot;PostgreSQL 논리복제와 FDW로 운영 서버를 두 번 죽여본 개발자의 실시간 데이터 동기화 생존기&quot;,&quot;alternativeHeadline&quot;:&quot;PostgreSQL Logical Replication과 FDW 실패 경험 및 해결 방안&quot;,&quot;description&quot;:&quot;PostgreSQL 논리복제(Logical Replication)와 FDW(Foreign Data Wrapper)를 사용하다 운영 서버를 다운시킨 실패 경험과 Tailscale VPN 환경에서의 실시간 계측 데이터 동기화 도전기. 복제 슬롯 관리, 트리거 타임아웃, 비동기 처리, 메시지 큐, CDC 등 해결 방안을 상세히 제시합니다.&quot;,&quot;author&quot;:{&quot;@type&quot;:&quot;Person&quot;,&quot;name&quot;:&quot;영환&quot;,&quot;url&quot;:&quot;https://odinbox.co.kr&quot;},&quot;publisher&quot;:{&quot;@type&quot;:&quot;Organization&quot;,&quot;name&quot;:&quot;OdinBOX&quot;,&quot;url&quot;:&quot;https://odinbox.co.kr&quot;},&quot;datePublished&quot;:&quot;2026-01-24&quot;,&quot;dateModified&quot;:&quot;2026-01-24&quot;,&quot;mainEntityOfPage&quot;:{&quot;@type&quot;:&quot;WebPage&quot;,&quot;@id&quot;:&quot;https://odinbox.co.kr/&quot;},&quot;keywords&quot;:[&quot;PostgreSQL&quot;,&quot;논리복제&quot;,&quot;Logical Replication&quot;,&quot;FDW&quot;,&quot;Foreign Data Wrapper&quot;,&quot;Tailscale VPN&quot;,&quot;실시간 데이터 동기화&quot;,&quot;분산 데이터베이스&quot;,&quot;CDC&quot;,&quot;Debezium&quot;,&quot;RabbitMQ&quot;,&quot;메시지 큐&quot;,&quot;복제 슬롯&quot;,&quot;WAL&quot;,&quot;데이터베이스 장애&quot;],&quot;articleSection&quot;:&quot;Database&quot;,&quot;inLanguage&quot;:&quot;ko-KR&quot;}
&lt;/script&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{&quot;@context&quot;:&quot;https://schema.org&quot;,&quot;@type&quot;:&quot;FAQPage&quot;,&quot;mainEntity&quot;:[{&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;PostgreSQL 논리복제가 서버를 다운시킬 수 있나요?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;네, 가능합니다. 특히 복제 슬롯(Replication Slot) 관리를 소홀히 하면 Subscriber가 오프라인일 때 WAL 로그가 무한히 쌓여 디스크가 꽉 차면서 DB가 다운될 수 있습니다. pg_replication_slots 뷰를 주기적으로 모니터링하고, 불필요한 슬롯은 pg_drop_replication_slot()으로 삭제해야 합니다.&quot;}},{&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;PostgreSQL FDW와 트리거를 함께 사용하면 위험한가요?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;주의가 필요합니다. 트리거 내에서 FDW를 통한 원격 쿼리는 동기식으로 처리되어 네트워크 지연 시 로컬 DB까지 블로킹됩니다. 반드시 connect_timeout과 statement_timeout을 설정하고, 예외 처리를 통해 원격 실패가 로컬 트랜잭션에 영향을 주지 않도록 해야 합니다.&quot;}},{&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;Tailscale VPN으로 PostgreSQL 데이터베이스 연결이 가능한가요?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;네, 가능합니다. Tailscale VPN은 WireGuard 기반의 Zero-config VPN으로 공인 IP 없이도 안전하게 DB에 접근할 수 있습니다. 다만 암호화 터널을 통과하는 쿼리마다 약간의 오버헤드가 발생하므로, 빈번한 쿼리가 필요한 실시간 동기화에서는 배치 처리나 비동기 방식을 권장합니다.&quot;}},{&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;실시간 데이터 동기화에서 동기식 대신 비동기식이 좋은 이유는?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;동기식 처리는 원격 서버에 문제가 생기면 로컬 시스템까지 영향을 받습니다. 비동기식은 로컬에서 큐 테이블이나 메시지 큐에 먼저 저장하고, 별도 프로세스가 서버로 전송하므로 원격 장애가 로컬에 영향을 주지 않습니다. RabbitMQ, Kafka, 또는 간단한 sync_queue 테이블 방식을 사용할 수 있습니다.&quot;}},{&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;PostgreSQL 복제 슬롯 WAL 누적을 모니터링하는 방법은?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal, active FROM pg_replication_slots; 쿼리로 확인할 수 있습니다. retained_wal이 1GB 이상이면 경고, 10GB 이상이면 즉시 조치가 필요합니다.&quot;}},{&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;FDW 연결에 타임아웃을 설정하는 방법은?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;ALTER SERVER 서버명 OPTIONS (ADD connect_timeout '10', ADD options '-c statement_timeout=30000'); 명령으로 설정합니다. connect_timeout은 연결 타임아웃(초 단위), statement_timeout은 쿼리 타임아웃(밀리초 단위)입니다.&quot;}}]}
&lt;/script&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{&quot;@context&quot;:&quot;https://schema.org&quot;,&quot;@type&quot;:&quot;HowTo&quot;,&quot;name&quot;:&quot;PostgreSQL 실시간 데이터 동기화 장애 복구 방법&quot;,&quot;description&quot;:&quot;FDW + 트리거 또는 논리복제로 인한 PostgreSQL 서버 장애 발생 시 응급 복구 절차&quot;,&quot;totalTime&quot;:&quot;PT20M&quot;,&quot;step&quot;:[{&quot;@type&quot;:&quot;HowToStep&quot;,&quot;name&quot;:&quot;문제가 되는 트리거 비활성화&quot;,&quot;text&quot;:&quot;ALTER TABLE 테이블명 DISABLE TRIGGER 트리거명; 명령으로 동기화 트리거를 즉시 비활성화합니다.&quot;,&quot;position&quot;:1},{&quot;@type&quot;:&quot;HowToStep&quot;,&quot;name&quot;:&quot;장시간 실행 쿼리 강제 종료&quot;,&quot;text&quot;:&quot;SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE now() - query_start &gt; interval '5 minutes' AND state != 'idle'; 로 오래 실행 중인 쿼리를 강제 종료합니다.&quot;,&quot;position&quot;:2},{&quot;@type&quot;:&quot;HowToStep&quot;,&quot;name&quot;:&quot;복제 슬롯 삭제로 WAL 해방&quot;,&quot;text&quot;:&quot;SELECT pg_drop_replication_slot('슬롯명'); 으로 WAL을 보관하고 있는 복제 슬롯을 삭제하여 디스크 공간을 확보합니다.&quot;,&quot;position&quot;:3},{&quot;@type&quot;:&quot;HowToStep&quot;,&quot;name&quot;:&quot;커넥션 상태 확인 및 정리&quot;,&quot;text&quot;:&quot;SELECT count(*) FROM pg_stat_activity; 로 현재 커넥션 수를 확인하고, 불필요한 idle 커넥션을 정리합니다.&quot;,&quot;position&quot;:4},{&quot;@type&quot;:&quot;HowToStep&quot;,&quot;name&quot;:&quot;서버 상태 모니터링&quot;,&quot;text&quot;:&quot;CPU, 메모리, 디스크 사용량을 확인하고 정상 범위로 돌아왔는지 확인합니다.&quot;,&quot;position&quot;:5}]}
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>FDW</category>
      <category>IoT수집</category>
      <category>LogicalReplication</category>
      <category>PostgreSQL</category>
      <category>TailscaleVPN</category>
      <category>개발삽질기</category>
      <category>논리복제</category>
      <category>분산데이터베이스</category>
      <category>실시간데이터동기화</category>
      <category>탄소중립(FEMS)</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/569</guid>
      <comments>https://odinbox.tistory.com/569#entry569comment</comments>
      <pubDate>Sat, 24 Jan 2026 21:49:34 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL FDW</title>
      <link>https://odinbox.tistory.com/568</link>
      <description>&lt;article class=&quot;post-fdw&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXVWBH/dJMcadgqVHq/UiyGElX1PK4R2FKWCzGSFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXVWBH/dJMcadgqVHq/UiyGElX1PK4R2FKWCzGSFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXVWBH/dJMcadgqVHq/UiyGElX1PK4R2FKWCzGSFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXVWBH%2FdJMcadgqVHq%2FUiyGElX1PK4R2FKWCzGSFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;header&gt;
&lt;p class=&quot;meta&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL 15 &amp;middot; Windows 환경 &amp;middot; FDW 실무 적용 &amp;middot; 이종 DB 연동&lt;/p&gt;
&lt;p class=&quot;lead&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL의 Foreign Data Wrapper(FDW)는 외부 데이터베이스를 로컬 테이블처럼 사용할 수 있도록 지원하는 기능입니다. 본 글에서는 PostgreSQL 15 Windows 환경을 기준으로 Postgres 간 연동부터 Oracle, MySQL, SQL Server 등 이종 데이터베이스를 실제 운영 환경에서 연결하고 활용하는 방법을 정리합니다.&lt;/p&gt;
&lt;/header&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;FDW 개요 및 Oracle DB Link와의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Foreign Data Wrapper(FDW)는 PostgreSQL에서 외부 데이터 소스를 외부 테이블(Foreign Table) 형태로 정의하여 SELECT, INSERT, UPDATE, DELETE를 수행할 수 있도록 해주는 기능입니다. 별도의 데이터 이관 없이도 실시간으로 외부 데이터베이스를 조회할 수 있어 시스템 통합 및 점진적 마이그레이션에 매우 유용합니다.&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;Oracle Database 역시 Database Link 기능을 통해 원격 데이터베이스 접근을 지원합니다. 다만 Oracle DB Link는 기본적으로 Oracle 간 연결에 최적화되어 있으며, 이종 데이터베이스 연동을 위해서는 Gateway 또는 별도 미들웨어 구성이 필요합니다. 반면 PostgreSQL FDW는 확장(extension) 기반 구조로 다양한 데이터베이스를 직접 연결할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;box info&quot;&gt;PostgreSQL FDW는 데이터 통합, 병행 운영, 단계적 전환 환경에서 특히 높은 효용을 보입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Postgres &amp;rarr; Postgres 연결 (postgres_fdw)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PostgreSQL 간 연동은 기본 제공되는 postgres_fdw를 사용합니다. 설정 절차는 다음과 같이 고정된 순서로 진행합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Extension 생성&lt;/li&gt;
&lt;li&gt;Foreign Server 등록&lt;/li&gt;
&lt;li&gt;User Mapping 생성&lt;/li&gt;
&lt;li&gt;Foreign Table 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;CREATE EXTENSION IF NOT EXISTS postgres_fdw;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;CREATE SERVER remote_pg_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '192.168.0.100', port '5432', dbname 'remote_db');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;CREATE USER MAPPING FOR CURRENT_USER
SERVER remote_pg_server
OPTIONS (user 'remote_user', password 'remote_password');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;CREATE FOREIGN TABLE public.remote_orders_ft (
order_id bigint,
customer_id bigint,
total_amt numeric,
created_at timestamp
)
SERVER remote_pg_server
OPTIONS (schema_name 'public', table_name 'orders');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;SELECT *
FROM public.remote_orders_ft
WHERE created_at &amp;gt; now() - interval '7 days';&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;box warn&quot;&gt;원격 PostgreSQL 접속이 되지 않는 경우 pg_hba.conf 설정, 포트 오픈, 방화벽 설정을 우선 확인합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Postgres &amp;rarr; Oracle 연결 (oracle_fdw)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oracle 데이터베이스 연동은 oracle_fdw 확장을 사용합니다. Windows 환경에서는 Oracle Instant Client 설치 여부와 PATH 설정이 정상 동작의 핵심 요소입니다.&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;Oracle Instant Client 설치 후 PATH 환경변수에 해당 경로를 반드시 포함해야 하며, PostgreSQL 서비스 재시작이 필요합니다.&lt;/p&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;CREATE EXTENSION IF NOT EXISTS oracle_fdw;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;CREATE SERVER ora_srv
FOREIGN DATA WRAPPER oracle_fdw
OPTIONS (dbserver '//ora.host.com:1521/XEPDB1');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;GRANT USAGE ON FOREIGN SERVER ora_srv TO postgres;

CREATE USER MAPPING FOR postgres
SERVER ora_srv
OPTIONS (user 'SCOTT', password 'tiger');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;CREATE FOREIGN TABLE public.ora_emp_ft (
empno numeric(4,0),
ename varchar(10),
sal numeric(7,2)
)
SERVER ora_srv
OPTIONS (schema 'SCOTT', table 'EMP', key 'EMPNO');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;SELECT *
FROM public.ora_emp_ft;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;box warn&quot;&gt;oracle_fdw DLL 로딩 오류는 대부분 Instant Client 경로 미인식 문제입니다. 서비스 계정 기준 PATH 설정까지 반드시 확인합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MySQL / SQL Server 등 기타 데이터베이스 연결 전략&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL은 mysql_fdw, SQL Server는 tds_fdw 또는 ODBC FDW를 활용할 수 있습니다. Windows 환경에서는 ODBC 드라이버 기반 접근 방식이 현실적인 선택이 되는 경우가 많습니다.&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;전용 FDW가 안정적으로 제공되는 경우에는 이를 우선 검토하며, 설치나 유지 관리가 어려운 경우 ODBC 기반 접근 방식을 선택하는 것이 운영 측면에서 유리합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;성능 설계 및 최적화 전략&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FDW는 네트워크를 통해 원격 쿼리를 수행하므로 성능 설계가 매우 중요합니다. 무분별한 사용은 오히려 시스템 전체 성능 저하로 이어질 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WHERE 조건을 최대한 명확히 작성하여 원격 필터링을 유도합니다.&lt;/li&gt;
&lt;li&gt;필요한 컬럼만 조회하여 데이터 전송량을 최소화합니다.&lt;/li&gt;
&lt;li&gt;외부 테이블에 대해 ANALYZE를 수행하여 실행 계획 품질을 개선합니다.&lt;/li&gt;
&lt;li&gt;대량 집계나 통계 쿼리는 원격 DB에서 View로 정리한 후 연결합니다.&lt;/li&gt;
&lt;li&gt;빈번한 조회 데이터는 주기적 적재 또는 구체화 전략을 병행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;box info&quot;&gt;FDW는 실시간 조회에 적합하며, 리포트&amp;middot;집계성 데이터는 배치 전략과 병행하는 것이 이상적입니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;보안 설계 시 고려 사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FDW는 외부 데이터베이스 접근 권한을 내부로 확장하는 구조이므로 보안 설계가 필수적입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;User Mapping 계정은 최소 권한 원칙으로 운영합니다.&lt;/li&gt;
&lt;li&gt;읽기 전용 목적이라면 SELECT 권한만 부여합니다.&lt;/li&gt;
&lt;li&gt;운영 계정과 연동 계정을 분리하여 사용합니다.&lt;/li&gt;
&lt;li&gt;Foreign Server 사용 권한은 필요한 사용자에게만 부여합니다.&lt;/li&gt;
&lt;li&gt;접속 이력 및 쿼리 로그를 통해 접근을 추적합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&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;FDW 쿼리 실패 시 서비스 영향도를 사전에 정의합니다.&lt;/li&gt;
&lt;li&gt;타임아웃 및 재시도 정책을 애플리케이션 레벨에서 고려합니다.&lt;/li&gt;
&lt;li&gt;외부 장애 발생 시 대체 경로 또는 캐시 데이터 활용을 준비합니다.&lt;/li&gt;
&lt;li&gt;중요 배치 작업은 FDW가 아닌 직접 적재 방식으로 분리합니다.&lt;/li&gt;
&lt;li&gt;연결 빈도 및 실패율을 지속적으로 모니터링합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PostgreSQL Foreign Data Wrapper는 단순한 외부 테이블 기능을 넘어 이종 데이터베이스를 유연하게 통합할 수 있는 강력한 도구입니다. 특히 Oracle 중심의 기존 환경에서 PostgreSQL로 점진적 전환을 고려하는 경우, FDW는 매우 현실적인 연결 해법이 됩니다.&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;다만 FDW는 만능이 아니며 성능, 보안, 장애 전파 측면을 충분히 고려한 설계가 필요합니다. 실시간 조회는 FDW로, 대량 처리와 핵심 리포트는 별도 적재 구조로 분리하는 전략이 장기적으로 안정적인 운영을 가능하게 합니다&lt;/p&gt;
&lt;/section&gt;
&lt;/article&gt;
&lt;div&gt;
&lt;style&gt;
.post-fdw { line-height: 1.8; color: #111; font-size: 15px; }
.post-fdw h1 { font-size: 2.1rem; margin-bottom: 0.8rem; }
.post-fdw h2 { font-size: 1.45rem; margin-top: 2.4rem; }
.post-fdw pre { background: #0b1020; color: #e8eeff; padding: 16px; border-radius: 14px; overflow-x: auto; }
.post-fdw code { font-family: Consolas, monospace; }
.post-fdw .lead { background: rgba(0,0,0,0.04); padding: 16px; border-radius: 14px; }
.post-fdw ul { margin-left: 20px; }
.post-fdw .box { padding: 14px 16px; border-radius: 14px; margin: 18px 0; }
.post-fdw .info { background: rgba(0, 123, 255, 0.08); }
.post-fdw .warn { background: rgba(255, 193, 7, 0.15); }
&lt;/style&gt;
&lt;/div&gt;</description>
      <category>DEVELOPMENT</category>
      <category>DBLink</category>
      <category>FDW</category>
      <category>MYSQL</category>
      <category>ODBC</category>
      <category>Oracle</category>
      <category>oracle_fdw</category>
      <category>PostgreSQL</category>
      <category>PostgreSQL15</category>
      <category>postgres_fdw</category>
      <category>SQLServer</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/568</guid>
      <comments>https://odinbox.tistory.com/568#entry568comment</comments>
      <pubDate>Sun, 18 Jan 2026 00:37:51 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL과 Python의 만남, PL/Python 활용부터 pg_cron 스케줄링까지</title>
      <link>https://odinbox.tistory.com/567</link>
      <description>&lt;div&gt;
&lt;style&gt;
    :root {
        --postgrespy_primary: #336791;
        --postgrespy_secondary: #ffd35c;
        --postgrespy_text: #333333;
        --postgrespy_bg: #ffffff;
        --postgrespy_code_bg: #282c34;
        --postgrespy_code_text: #abb2bf;
        --postgrespy_border: #e1e4e8;
        --postgrespy_accent: #d32f2f;
    }

    .postgrespy_container {
        font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, sans-serif;
        line-height: 1.8;
        color: var(--postgrespy_text);
        max-width: 900px;
        margin: 0 auto;
        padding: 40px 20px;
        background-color: var(--postgrespy_bg);
        overflow-x: hidden;
    }

    .postgrespy_thumbnail {
        text-align: center;
        margin-bottom: 40px;
    }

    .postgrespy_title {
        font-size: 2.5rem;
        font-weight: 800;
        color: #1a1a1a;
        margin-bottom: 10px;
        letter-spacing: -0.05rem;
    }

    .postgrespy_subtitle {
        font-size: 1.1rem;
        color: #666;
        margin-bottom: 50px;
        border-bottom: 2px solid var(--postgrespy_border);
        padding-bottom: 20px;
    }

    .postgrespy_h2 {
        font-size: 1.8rem;
        font-weight: 700;
        color: var(--postgrespy_primary);
        margin-top: 60px;
        margin-bottom: 20px;
        display: flex;
        align-items: center;
    }

    .postgrespy_h2::before {
        content: '';
        display: block;
        width: 8px;
        height: 30px;
        background-color: var(--postgrespy_secondary);
        margin-right: 15px;
        border-radius: 4px;
    }

    .postgrespy_h3 {
        font-size: 1.4rem;
        font-weight: 600;
        margin-top: 40px;
        margin-bottom: 15px;
        color: #2c3e50;
    }

    .postgrespy_p {
        margin-bottom: 20px;
        font-size: 1.05rem;
        word-break: keep-all;
    }

    .postgrespy_code_wrapper {
        position: relative;
        margin: 30px 0;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        transition: transform 0.3s ease;
    }

    .postgrespy_code_wrapper:hover {
        transform: translateY(-5px);
    }

    .postgrespy_code_header {
        background-color: #21252b;
        color: #fff;
        padding: 8px 15px;
        font-size: 0.85rem;
        font-family: monospace;
        border-bottom: 1px solid #3e4451;
        display: flex;
        justify-content: space-between;
    }

    .postgrespy_code_block {
        background-color: var(--postgrespy_code_bg);
        color: var(--postgrespy_code_text);
        padding: 20px;
        overflow-x: auto;
        font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
        font-size: 0.95rem;
        line-height: 1.6;
        margin: 0;
    }

    .postgrespy_keyword { color: #c678dd; }
    .postgrespy_function { color: #61afef; }
    .postgrespy_string { color: #98c379; }
    .postgrespy_comment { color: #5c6370; font-style: italic; }

    .postgrespy_info_box {
        background-color: #f1f8ff;
        border-left: 5px solid var(--postgrespy_primary);
        padding: 20px;
        margin: 30px 0;
        border-radius: 0 8px 8px 0;
    }

    .postgrespy_warning_box {
        background-color: #fff5f5;
        border-left: 5px solid var(--postgrespy_accent);
        padding: 20px;
        margin: 30px 0;
        border-radius: 0 8px 8px 0;
    }

    .postgrespy_box_title {
        display: block;
        font-weight: 700;
        margin-bottom: 10px;
        font-size: 1.1rem;
    }

    .postgrespy_fade_in {
        opacity: 0;
        transform: translateY(20px);
        transition: opacity 0.8s ease-out, transform 0.8s ease-out;
    }

    .postgrespy_visible {
        opacity: 1;
        transform: translateY(0);
    }

    .postgrespy_list {
        margin-left: 20px;
        margin-bottom: 20px;
    }
    .postgrespy_list li {
        margin-bottom: 10px;
    }

    @media (max-width: 768px) {
        .postgrespy_title { font-size: 2rem; }
        .postgrespy_h2 { font-size: 1.5rem; }
        .postgrespy_code_block { font-size: 0.85rem; }
    }
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespy_container&quot;&gt;
&lt;div class=&quot;postgrespy_thumbnail&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtTMVG/dJMcac9BOPQ/VA9D833Jo3iMNjs0x7GFYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtTMVG/dJMcac9BOPQ/VA9D833Jo3iMNjs0x7GFYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtTMVG/dJMcac9BOPQ/VA9D833Jo3iMNjs0x7GFYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtTMVG%2FdJMcac9BOPQ%2FVA9D833Jo3iMNjs0x7GFYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;header&gt;
&lt;p class=&quot;postgrespy_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;단순한 SMTP 전송을 넘어, 데이터 분석부터 오라클 DB Job 대체까지&lt;/p&gt;
&lt;/header&gt;
&lt;section class=&quot;postgrespy_fade_in&quot;&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;이전 포스팅(&lt;a style=&quot;color: var(--postgrespy_primary); text-decoration: underline;&quot; href=&quot;https://odinbox.co.kr/562&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://odinbox.co.kr/562&lt;/a&gt;)에서 우리는 PostgreSQL에서 Python을 연동하여 SMTP 메일을 발송하는 방법을 다루었습니다. 하지만 이것은 PL/Python이 가진 잠재력의 극히 일부에 불과합니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;많은 분이 &quot;Python으로 만든 함수의 결과값을 SQL 쿼리 내에서 바로 사용할 수 있는가?&quot;, &quot;외부 API와 통신하여 데이터를 가져와 DB에 넣을 수 있는가?&quot;, 그리고 &quot;오라클의 DB Job처럼 스케줄링이 가능한가?&quot;에 대해 궁금합니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 PostgreSQL의 확장 기능인 &lt;b&gt;PL/Python&lt;/b&gt;을 활용하여 Python의 방대한 라이브러리 생태계를 DB 내부로 가져오는 방법과, &lt;b&gt;pg_cron&lt;/b&gt;을 이용해 Python 프로시저를 주기적으로 실행하는 스케줄링 구현 방법까지, &lt;b&gt;OdinBOX&lt;/b&gt; 예제 코드를 통해 상세하게 정리해 드립니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section class=&quot;postgrespy_fade_in&quot;&gt;
&lt;h2 class=&quot;postgrespy_h2&quot; data-ke-size=&quot;size26&quot;&gt;1. PL/Python의 이해와 설정 (Trusted vs Untrusted)&lt;/h2&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL에서 Python을 사용하려면 &lt;code&gt;plpython3u&lt;/code&gt; 확장을 설치해야 합니다. 여기서 뒤에 붙은 'u'는 &lt;b&gt;Untrusted(신뢰할 수 없음)&lt;/b&gt;를 의미합니다. 이는 보안상의 이유로 붙은 이름이지만, 역설적으로 '제약이 없다'는 뜻이기도 합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_info_box&quot;&gt;&lt;span style=&quot;color: var(--postgrespy_primary);&quot; class=&quot;postgrespy_box_title&quot;&gt;Trusted vs Untrusted 차이점&lt;/span&gt;
&lt;ul class=&quot;postgrespy_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Trusted (plpgSQL 등) :&lt;/b&gt; DB 내부 데이터만 건드릴 수 있으며, 파일 시스템이나 네트워크 접근이 차단됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Untrusted (plpython3u) :&lt;/b&gt; Python이 할 수 있는 모든 것을 할 수 있습니다. OS 파일 읽기/쓰기, 소켓 통신, 외부 API 요청 등이 가능합니다. 즉, &lt;b&gt;슈퍼유저 권한&lt;/b&gt;이 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;먼저 해당 기능을 활성화합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_code_wrapper&quot;&gt;
&lt;div class=&quot;postgrespy_code_header&quot;&gt;SQL Command&lt;/div&gt;
&lt;pre class=&quot;postgrespy_code_block n1ql&quot;&gt;&lt;code&gt;CREATE EXTENSION plpython3u;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;postgrespy_fade_in&quot;&gt;
&lt;h2 class=&quot;postgrespy_h2&quot; data-ke-size=&quot;size26&quot;&gt;2. Python 함수 제작 및 결과값 활용&lt;/h2&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;Python으로 로직을 짜고 그 결과값을 SQL 문에서 `SELECT` 하거나 `WHERE` 절 조건으로 즉시 사용할 수 있습니다. 복잡한 텍스트 처리나 정규식 연산은 SQL보다 Python이 훨씬 강력하고 간결합니다.&lt;/p&gt;
&lt;h3 class=&quot;postgrespy_h3&quot; data-ke-size=&quot;size23&quot;&gt;예제 1, OdinBOX 텍스트 분석기&lt;/h3&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;입력받은 텍스트에서 키워드를 추출하여 JSON 형태로 반환하는 함수를 만들어 보겠습니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_code_wrapper&quot;&gt;
&lt;div class=&quot;postgrespy_code_header&quot;&gt;PostgreSQL Function (PL/Python)&lt;/div&gt;
&lt;pre class=&quot;postgrespy_code_block pgsql&quot;&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION odinbox_analyze_text(input_text text)
RETURNS json
AS $$
    import json
    import re

    words = re.findall(r'\w+', input_text.lower())
    word_count = {}
    
    for word in words:
        if word in word_count:
            word_count[word] += 1
        else:
            word_count[word] = 1
            
    result = {
        &quot;status&quot;: &quot;success&quot;,
        &quot;analyzer&quot;: &quot;OdinBOX_v1&quot;,
        &quot;total_words&quot;: len(words),
        &quot;data&quot;: word_count
    }
    
    return json.dumps(result)
$$ LANGUAGE plpython3u;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;이제 이 함수를 일반 SQL처럼 조회할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_code_wrapper&quot;&gt;
&lt;div class=&quot;postgrespy_code_header&quot;&gt;Usage Example&lt;/div&gt;
&lt;pre class=&quot;postgrespy_code_block reasonml&quot;&gt;&lt;code&gt;SELECT odinbox_analyze_text('OdinBOX is great. OdinBOX uses Postgres.');&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;postgrespy_fade_in&quot;&gt;
&lt;h2 class=&quot;postgrespy_h2&quot; data-ke-size=&quot;size26&quot;&gt;3. 외부 라이브러리 활용 : DB에서 직접 웹 크롤링하기&lt;/h2&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;DB 서버에 &lt;code&gt;requests&lt;/code&gt;나 &lt;code&gt;pandas&lt;/code&gt; 라이브러리가 설치되어 있다면(&lt;code&gt;pip install requests&lt;/code&gt;), DB 함수 내에서 이를 import하여 외부 데이터를 실시간으로 가져올 수 있습니다. 이는 ETL 도구 없이도 외부 데이터를 적재할 수 있음을 의미합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_code_wrapper&quot;&gt;
&lt;div class=&quot;postgrespy_code_header&quot;&gt;OdinBOX External Data Fetcher&lt;/div&gt;
&lt;pre class=&quot;postgrespy_code_block sql&quot;&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION odinbox_fetch_currency(currency_code text)
RETURNS numeric
AS $$
    import requests
    
    try:
        url = f&quot;https://api.exchangerate-api.com/v4/latest/{currency_code}&quot;
        response = requests.get(url, timeout=5)
        
        if response.status_code == 200:
            data = response.json()
            return data['rates'].get('KRW', 0)
        else:
            plpy.warning(f&quot;OdinBOX API Error: {response.status_code}&quot;)
            return -1
    except Exception as e:
        plpy.error(f&quot;Network Error: {e}&quot;)
$$ LANGUAGE plpython3u;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;postgrespy_fade_in&quot;&gt;
&lt;h2 class=&quot;postgrespy_h2&quot; data-ke-size=&quot;size26&quot;&gt;4. 오라클 DB Job 대체하기 : pg_cron과 Python의 만남&lt;/h2&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;오라클에는 &lt;code&gt;DBMS_SCHEDULER&lt;/code&gt;나 &lt;code&gt;DBMS_JOB&lt;/code&gt;이 내장되어 있습니다. PostgreSQL은 기본적으로는 스케줄러가 없지만, 표준처럼 사용되는 확장 기능인 &lt;b&gt;pg_cron&lt;/b&gt;을 통해 동일한 기능을 수행할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;이 조합이 강력한 이유는, &lt;b&gt;&quot;Python으로 복잡한 로직을 짜고, pg_cron으로 스케줄링&quot;&lt;/b&gt;할 수 있기 때문입니다.&lt;/p&gt;
&lt;h3 class=&quot;postgrespy_h3&quot; data-ke-size=&quot;size23&quot;&gt;Step 1. pg_cron 설치 및 설정&lt;/h3&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;postgresql.conf&lt;/code&gt; 파일의 &lt;code&gt;shared_preload_libraries&lt;/code&gt;에 &lt;code&gt;pg_cron&lt;/code&gt;을 추가하고 DB를 재시작해야 합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_code_wrapper&quot;&gt;
&lt;pre class=&quot;postgrespy_code_block pgsql&quot;&gt;&lt;code&gt;CREATE EXTENSION pg_cron;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;postgrespy_h3&quot; data-ke-size=&quot;size23&quot;&gt;Step 2. Python 프로시저 스케줄링 등록&lt;/h3&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, 매일 오전 9시에 위에서 만든 &lt;code&gt;odinbox_fetch_currency&lt;/code&gt; 함수를 실행하여 환율 테이블에 저장하는 작업을 등록해 보겠습니다.&lt;/p&gt;
&lt;div class=&quot;postgrespy_code_wrapper&quot;&gt;
&lt;div class=&quot;postgrespy_code_header&quot;&gt;Schedule Registration&lt;/div&gt;
&lt;pre class=&quot;postgrespy_code_block sql&quot;&gt;&lt;code&gt;CREATE TABLE odinbox_currency_log (
    log_time TIMESTAMP DEFAULT now(),
    usd_rate NUMERIC
);

CREATE OR REPLACE PROCEDURE odinbox_daily_job()
LANGUAGE sql
AS $$
    INSERT INTO odinbox_currency_log (usd_rate)
    SELECT odinbox_fetch_currency('USD');
$$;

SELECT cron.schedule('odinbox_exchange_job', '0 9 * * *', 'CALL odinbox_daily_job()');&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespy_warning_box&quot;&gt;&lt;span style=&quot;color: var(--postgrespy_accent);&quot; class=&quot;postgrespy_box_title&quot;&gt;주의사항&lt;/span&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;pg_cron은 기본적으로 GMT 기준입니다. 한국 시간(KST)으로 9시에 실행하려면 시간을 -9시간 하여 &lt;code&gt;0 0 * * *&lt;/code&gt;(자정)으로 설정하거나, &lt;code&gt;cron.timezone&lt;/code&gt; 설정을 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;postgrespy_fade_in&quot;&gt;
&lt;h2 class=&quot;postgrespy_h2&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL의 PL/Python은 단순히 DB 안에서 스크립트를 돌리는 수준을 넘어, 데이터베이스를 &lt;b&gt;지능형 데이터 허브&lt;/b&gt;로 만들어줍니다. Python의 강력한 라이브러리(Pandas, Scikit-learn, Requests 등)를 데이터가 저장된 곳에서 바로 실행함으로써 이동 비용을 줄이고 효율을 극대화할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;postgrespy_p&quot; data-ke-size=&quot;size16&quot;&gt;또한 &lt;code&gt;pg_cron&lt;/code&gt;과 결합하면 오라클의 DB Job 부럽지 않은 강력한 스케줄링 환경을 구축할 수 있습니다. 오늘 소개한 &lt;b&gt;OdinBOX&lt;/b&gt; 예제들을 응용하여 여러분만의 자동화 시스템을 구축해 보시기 바랍니다.&lt;/p&gt;
&lt;/section&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
    document.addEventListener(&quot;DOMContentLoaded&quot;, function() {
        const observerOptions = {
            root: null,
            rootMargin: '0px',
            threshold: 0.1
        };

        const observer = new IntersectionObserver((entries, observer) =&gt; {
            entries.forEach(entry =&gt; {
                if (entry.isIntersecting) {
                    entry.target.classList.add('postgrespy_visible');
                    observer.unobserve(entry.target);
                }
            });
        }, observerOptions);

        const fadeElements = document.querySelectorAll('.postgrespy_fade_in');
        fadeElements.forEach(el =&gt; observer.observe(el));
    });
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>DBJOB</category>
      <category>DB튜닝</category>
      <category>pg_cron</category>
      <category>PLPython</category>
      <category>PostgreSQL</category>
      <category>python</category>
      <category>SQL파이썬함수</category>
      <category>데이터베이스</category>
      <category>백엔드</category>
      <category>자동화</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/567</guid>
      <comments>https://odinbox.tistory.com/567#entry567comment</comments>
      <pubDate>Sun, 11 Jan 2026 11:00:00 +0900</pubDate>
    </item>
    <item>
      <title>AI 에이전트(AI Agent)를 활용한 업무 자동화 및 멀티 에이전트 기반 코드 최적화 전략</title>
      <link>https://odinbox.tistory.com/566</link>
      <description>&lt;div&gt;
&lt;style&gt;
        /* [CSS] 모든 클래스 및 아이디에 aiagentodin_ 접두사 적용 */
        .aiagentodin_container {
            line-height: 1.9;
            color: #1a1a1a;
            max-width: 1000px;
            margin: 0 auto;
            padding: 40px 20px;
            font-family: 'Pretendard', -apple-system, sans-serif;
            background-color: #ffffff;
        }
        #aiagentodin_title_box {
            border-bottom: 4px solid #0056b3;
            padding-bottom: 20px;
            margin-bottom: 50px;
        }
        .aiagentodin_main_h1 {
            font-size: 2.5rem;
            color: #003366;
            margin: 0;
            word-break: keep-all;
        }
        .aiagentodin_section_h2 {
            font-size: 1.8rem;
            color: #004085;
            background-color: #f8f9fa;
            padding: 15px 20px;
            border-left: 10px solid #007bff;
            margin-top: 60px;
            margin-bottom: 25px;
        }
        .aiagentodin_section_h3 {
            font-size: 1.4rem;
            color: #10ac84;
            margin-top: 35px;
            padding-bottom: 5px;
            border-bottom: 1px solid #eee;
        }
        .aiagentodin_paragraph {
            margin-bottom: 20px;
            text-align: justify;
        }
        .aiagentodin_info_panel {
            background-color: #e9ecef;
            border-radius: 8px;
            padding: 25px;
            margin: 30px 0;
            border-left: 5px solid #6c757d;
        }
        /* [코드 블록 스타일 개선] 고대비 색상 적용 */
        .aiagentodin_code_area {
            position: relative;
            background-color: #1e1e1e; /* VS Code Dark 스타일 */
            border-radius: 10px;
            margin: 25px 0;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
        }
        .aiagentodin_code_toolbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 20px;
            background-color: #333333;
            border-radius: 10px 10px 0 0;
            color: #ffffff;
            font-size: 0.85rem;
        }
        .aiagentodin_copy_button {
            background-color: #007bff;
            color: white;
            border: none;
            padding: 5px 15px;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
            transition: background 0.2s;
        }
        .aiagentodin_copy_button:hover {
            background-color: #0056b3;
        }
        .aiagentodin_pre_tag {
            margin: 0;
            padding: 20px;
            overflow-x: auto;
            color: #d4d4d4;
            font-family: 'Fira Code', 'Consolas', monospace;
            font-size: 0.95rem;
            line-height: 1.5;
        }
        /* 코드 구문 강조 색상 */
        .aiagentodin_code_keyword { color: #569cd6; } /* 파란색 */
        .aiagentodin_code_string { color: #ce9178; }  /* 주황색 */
        .aiagentodin_code_comment { color: #6a9955; } /* 초록색 */
        .aiagentodin_code_func { color: #dcdcaa; }    /* 연노랑 */
        .aiagentodin_code_var { color: #9cdcfe; }     /* 하늘색 */

        .aiagentodin_list {
            margin-bottom: 25px;
            padding-left: 20px;
        }
        .aiagentodin_list_item {
            margin-bottom: 12px;
        }
        .aiagentodin_bold {
            font-weight: bold;
            color: #d63031;
        }
        .aiagentodin_footer_tags {
            margin-top: 80px;
            padding: 30px;
            background-color: #f1f2f6;
            border-radius: 10px;
        }
    &lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;aiagentodin_container&quot;&gt;&lt;header id=&quot;aiagentodin_title_box&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (4).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cofej3/dJMcaa41hyp/sCKKfnx0EAPwX2y3wIrFT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cofej3/dJMcaa41hyp/sCKKfnx0EAPwX2y3wIrFT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cofej3/dJMcaa41hyp/sCKKfnx0EAPwX2y3wIrFT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcofej3%2FdJMcaa41hyp%2FsCKKfnx0EAPwX2y3wIrFT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (4).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p class=&quot;aiagentodin_main_h1&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;text-align: justify; color: #1a1a1a; font-size: 16px; letter-spacing: 0px;&quot;&gt;인공지능 기술이 단순한 생성형 언어 모델(LLM)을 넘어, 스스로 사고하고 행동하는 &lt;/span&gt;&lt;b&gt;AI 에이전트(AI Agent)&lt;/b&gt;&lt;span style=&quot;text-align: justify; color: #1a1a1a; font-size: 16px; letter-spacing: 0px;&quot;&gt; 시대로 완벽하게 진입했습니다. 2026년 현재, 에이전틱 워크플로우(Agentic Workflow)는 기업의 생산성을 결정짓는 핵심 요소가 되었습니다. 단순한 질의응답을 넘어 사용자의 목표를 달성하기 위해 계획을 수립하고, 도구를 선택하며, 결과물을 비판적으로 검토하는 자율성이 에이전트의 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;section&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;AI 에이전트의 정의와 작동 원리를 사실에 근거하여 상세히 분석하고, 특히 개발 분야에서 각기 다른 역할을 부여받은 멀티 에이전트들이 어떻게 협업하여 최적의 소스코드를 도출하는지 그 프로세스를 구체적으로 다룹니다. 또한 OpenAI와 Google Gemini를 활용한 실전 구현 방법까지 적었습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;1. AI 에이전트의 논리적 아키텍처와 작동 원리&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;AI 에이전트는 거대언어모델(LLM)을 '두뇌'로 삼고, 외부 환경과 상호작용할 수 있는 '도구'와 '메모리'를 결합한 시스템입니다. 학술적으로 에이전트의 자율성은 다음과 같은 4단계 루프에 의해 구현됩니다.&lt;/p&gt;
&lt;div class=&quot;aiagentodin_info_panel&quot;&gt;
&lt;ul class=&quot;aiagentodin_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;인지(Perception) :&lt;/span&gt; 사용자의 요청과 현재 환경 데이터(파일, 웹 검색 결과 등)를 받아들입니다.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;계획(Planning) :&lt;/span&gt; 목표를 달성하기 위해 필요한 일련의 작업 순서를 논리적으로 분해합니다. (예 : Chain of Thought 기법 활용)&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;추론(Reasoning) :&lt;/span&gt; 각 단계에서 어떤 도구(API, 계산기, 코드 실행기)를 사용할지 결정합니다.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;실행 및 성찰(Action &amp;amp; Reflection) :&lt;/span&gt; 도구를 실행한 뒤 그 결과를 관찰하고, 목표에 부합하지 않으면 계획을 수정하여 다시 시도합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;2. 멀티 에이전트를 활용한 코드 제작 및 최적화 방법&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;하나의 AI가 모든 코드를 짜는 것보다, 역할이 분산된 여러 에이전트가 상호 검토하는 방식이 코드 품질(신뢰성, 보안성, 효율성) 면에서 압도적으로 우수합니다. 이를 &lt;b&gt;멀티 에이전트 협업 시스템&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;h3 class=&quot;aiagentodin_section_h3&quot; data-ke-size=&quot;size23&quot;&gt;역할 분담 예시 : 코드 최적화 파이프라인&lt;/h3&gt;
&lt;ul class=&quot;aiagentodin_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;Planner Agent :&lt;/span&gt; 전체적인 아키텍처를 설계하고 필요한 라이브러리와 데이터 구조를 정의합니다.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;Developer Agent :&lt;/span&gt; 설계에 따라 실제 구현 코드를 작성합니다.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;Code Auditor Agent :&lt;/span&gt; 작성된 코드를 비판적으로 검토합니다. 메모리 누수, 시간 복잡도, 보안 취약점을 찾아냅니다.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;Test Engineer Agent :&lt;/span&gt; 단위 테스트 코드를 작성하고 실행하여 예상치 못한 버그를 탐지합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;이들은 서로 메시지를 주고받으며 피드백 루프를 돕니다. 예시 : Auditor가 수정을 요청하면 Developer가 다시 코드를 작성하는 과정을 &quot;최적의 소스코드&quot;가 나올 때까지 반복합니다.&lt;/p&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;3. 에이전트 구현을 위한 환경 설정&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;AI 에이전트를 구축하기 위해서는 Python 환경과 주요 라이브러리 설치가 필요합니다. 본 가이드는 2026년 표준인 LangChain(v0.4+)과 CrewAI를 기준으로 설명합니다.&lt;/p&gt;
&lt;div class=&quot;aiagentodin_code_area&quot;&gt;
&lt;div class=&quot;aiagentodin_code_toolbar&quot;&gt;&lt;span&gt;Terminal - Dependencies&lt;/span&gt; &lt;button class=&quot;aiagentodin_copy_button&quot;&gt;복사하기&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;aiagentodin_sh_1&quot; class=&quot;aiagentodin_pre_tag cmake&quot;&gt;&lt;code&gt;# 필수 라이브러리 설치
pip install langchain-openai langchain-google-genai crewai python-dotenv&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;4. OpenAI 기반 AI 에이전트 구현 방법&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;OpenAI의 모델(GPT-4o 등)은 추론 능력이 뛰어나 에이전트의 두뇌로 적합합니다.&lt;/p&gt;
&lt;div class=&quot;aiagentodin_code_area&quot;&gt;
&lt;div class=&quot;aiagentodin_code_toolbar&quot;&gt;&lt;span&gt;Python - OpenAI Agent&lt;/span&gt; &lt;button class=&quot;aiagentodin_copy_button&quot;&gt;복사하기&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;aiagentodin_py_1&quot; class=&quot;aiagentodin_pre_tag routeros&quot;&gt;&lt;code&gt;import os
from langchain_openai import ChatOpenAI
from crewai import Agent, Task, Crew

# API 키 설정
os.environ[&quot;OPENAI_API_KEY&quot;] = &quot;YOUR_OPENAI_API_KEY&quot;

# OpenAI 기반 에이전트 정의
aiagentodin_openai_llm = ChatOpenAI(model=&quot;gpt-4o&quot;, temperature=0.2)

aiagentodin_coder = Agent(
    role='Senior Python Developer',
    goal='효율적이고 읽기 쉬운 파이썬 코드 작성',
    backstory='당신은 20년 경력의 베테랑 개발자입니다.',
    llm=aiagentodin_openai_llm
)

# 작업 수행
aiagentodin_task = Task(description='정렬 알고리즘 최적화 코드 작성', agent=aiagentodin_coder)
aiagentodin_crew = Crew(agents=[aiagentodin_coder], tasks=[aiagentodin_task])
print(aiagentodin_crew.kickoff())&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;5. Google Gemini 기반 AI 에이전트 구현 방법&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;Gemini 모델은 방대한 컨텍스트 창과 빠른 처리 속도를 자랑합니다. 멀티모달 능력이 필요한 에이전트에 유리합니다.&lt;/p&gt;
&lt;div class=&quot;aiagentodin_code_area&quot;&gt;
&lt;div class=&quot;aiagentodin_code_toolbar&quot;&gt;&lt;span&gt;Python - Gemini Agent&lt;/span&gt; &lt;button class=&quot;aiagentodin_copy_button&quot;&gt;복사하기&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;aiagentodin_py_2&quot; class=&quot;aiagentodin_pre_tag routeros&quot;&gt;&lt;code&gt;from langchain_google_genai import ChatGoogleGenerativeAI

# Gemini API 키 설정
os.environ[&quot;GOOGLE_API_KEY&quot;] = &quot;YOUR_GEMINI_API_KEY&quot;

# Gemini 기반 에이전트 두뇌 설정
aiagentodin_gemini_llm = ChatGoogleGenerativeAI(
    model=&quot;gemini-1.5-pro&quot;, 
    temperature=0.3,
    convert_system_message_to_human=True
)

aiagentodin_reviewer = Agent(
    role='Code Review Specialist',
    goal='코드의 보안 취약점을 정밀 분석',
    backstory='당신은 글로벌 보안 기업의 화이트해커 출신 리뷰어입니다.',
    llm=aiagentodin_gemini_llm
)

# 이후 Crew 및 Task 구성은 위와 동일하게 연동 가능&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;6. AI 에이전트 업무 자동화 구축 프로세스&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;에이전트를 통해 업무를 자동화하려면 다음 단계를 준수해야 성공률이 높습니다.&lt;/p&gt;
&lt;ul class=&quot;aiagentodin_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;단계 1 : 워크플로우 분석 :&lt;/span&gt; 자동화할 업무의 입력을 정의합니다. 예시 : &quot;매일 아침 9시 뉴스 리서치 및 보고서 이메일 발송&quot;.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;단계 2 : 도구(Tools) 바인딩 :&lt;/span&gt; 에이전트가 사용할 도구를 정의합니다. 예시 : SerpApi(검색), Gmail API(메일), Pandas(데이터 분석).&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;단계 3 : 에이전트 페르소나 설정 :&lt;/span&gt; 에이전트에게 아주 구체적인 지시사항을 부여합니다.&lt;/li&gt;
&lt;li class=&quot;aiagentodin_list_item&quot;&gt;&lt;span class=&quot;aiagentodin_bold&quot;&gt;단계 4 : 오류 처리 및 성찰 설계 :&lt;/span&gt; 에이전트가 실패했을 때 스스로 원인을 파악하고 재시도하는 로직을 프롬프트에 포함합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&quot;aiagentodin_section_h2&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p class=&quot;aiagentodin_paragraph&quot; data-ke-size=&quot;size16&quot;&gt;AI 에이전트는 단순한 도구를 넘어 인간의 지능적 동반자로 자리 잡았습니다. 특히, 멀티 에이전트 시스템을 통한 코드 최적화는 개발 속도를 획기적으로 높이는 동시에 인적 오류를 최소화하는 강력한 수단입니다. OpenAI와 Gemini 등 각 모델의 특성에 맞춰 에이전트를 설계한다면, 여러분의 업무 환경은 이전과는 전혀 다른 차원의 효율성을 경험하게 될 것입니다.&lt;/p&gt;
&lt;footer class=&quot;aiagentodin_footer_tags&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Tags&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#AI에이전트 #AIAgent #업무자동화 #OpenAI #Gemini #멀티에이전트 #코드최적화 #LangChain #CrewAI #인공지능프로그래밍&lt;/p&gt;
&lt;/footer&gt;&lt;/header&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
    function aiagentodin_copy(aiagentodin_target_id) {
        const aiagentodin_text_content = document.getElementById(aiagentodin_target_id).innerText;
        navigator.clipboard.writeText(aiagentodin_text_content).then(() =&gt; {
            alert(&quot;소스 코드가 성공적으로 클립보드에 복사되었습니다.&quot;);
        }).catch(err =&gt; {
            console.error('복사 중 오류 발생 : ', err);
            alert(&quot;복사에 실패했습니다. 수동으로 복사해 주세요.&quot;);
        });
    }
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>2026 AI 기술 트렌드</category>
      <category>Agent 자동화 가이드</category>
      <category>AI 에이전트 제작 방법</category>
      <category>OpenAI 에이전트</category>
      <category>랭체인 에이전트 사용법</category>
      <category>멀티 에이전트 협업 시스템</category>
      <category>인공지능 에이전트 아키텍처</category>
      <category>제미나이 AI 에이전트 활용</category>
      <category>코드 최적화 AI 솔루션</category>
      <category>파이썬 업무 자동화 코드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/566</guid>
      <comments>https://odinbox.tistory.com/566#entry566comment</comments>
      <pubDate>Sat, 3 Jan 2026 10:41:28 +0900</pubDate>
    </item>
    <item>
      <title>원망했던 나의 아버지, 하늘로 보내드리며 적는 편지</title>
      <link>https://odinbox.tistory.com/565</link>
      <description>&lt;div style=&quot;line-height: 2.0; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif; color: #333; max-width: 800px; margin: auto; padding: 40px 20px; word-break: keep-all;&quot;&gt;
&lt;h1 style=&quot;border-bottom: 2px solid #222; padding-bottom: 20px; color: #000; font-size: 1.7em; text-align: center; line-height: 1.4;&quot;&gt;지독했던 원망 끝에 아버지를 보냈습니다.&lt;br /&gt;술 냄새 속에 가려졌던 당신의 진심&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ClickERP.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsvH0w/dJMcaf6gZZH/DBFxpXOq1e8313dH1BDYJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsvH0w/dJMcaf6gZZH/DBFxpXOq1e8313dH1BDYJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsvH0w/dJMcaf6gZZH/DBFxpXOq1e8313dH1BDYJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsvH0w%2FdJMcaf6gZZH%2FDBFxpXOq1e8313dH1BDYJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1280&quot; data-filename=&quot;ClickERP.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;text-align: center; color: #999; font-size: 0.9em; margin-bottom: 50px;&quot; data-ke-size=&quot;size16&quot;&gt;2025. 12. 24. 소리 내지 못한 고백&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 12월 7일, 아버지가 세상을 떠나셨습니다. 이틀 뒤인 12월 9일, 입관과 발인을 거쳐 화장까지 마쳤습니다. 경제적인 사정과 여러 이유로 가족들과 고심 끝에 &lt;b&gt;'무빈소 장례'&lt;/b&gt;를 치렀습니다. 빈소도 없이 아버지를 보내드리는 길, 차가운 공기만큼이나 가슴 한구석이 무겁고 씁쓸했습니다.&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;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rH49j/dJMb99LKvx5/3TpG01EUxbLmAvHZtrpCL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rH49j/dJMb99LKvx5/3TpG01EUxbLmAvHZtrpCL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rH49j/dJMb99LKvx5/3TpG01EUxbLmAvHZtrpCL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrH49j%2FdJMb99LKvx5%2F3TpG01EUxbLmAvHZtrpCL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div style=&quot;margin: 50px 0; padding: 30px; border-left: 4px solid #555; background-color: #fcfcfc;&quot;&gt;
&lt;h2 style=&quot;font-size: 1.3em; color: #222; margin-top: 0;&quot; data-ke-size=&quot;size26&quot;&gt;아버지의 술 냄새, 그리고 나의 상처&lt;/h2&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;'안 먹는 것'&lt;/b&gt;에 가깝습니다. 당신처럼 살고 싶지 않다는 처절한 거부였고, 제 인생만큼은 술 냄새 없는 온전한 것이길 바랐기 때문입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어린 시절 앓으셨던 열병은 아버지의 삶을 송두리째 앗아갔습니다. 뒤틀린 걸음걸이, 침침해진 눈, 잘 들리지 않던 귀... 그 불편한 몸으로 세상을 살아내는 것이 얼마나 고단하셨을까요. 원망의 뒤편에는 늘 그 가냘픈 뒷모습에 대한 연민이 있었습니다. 상처를 주었지만, 그래도 당신은 제게 단 하나뿐인 아버지였습니다.&lt;/p&gt;
&lt;blockquote style=&quot;background: #f9f9f9; border: 1px solid #eee; padding: 30px; margin: 40px 0; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;font-size: 1.2em; color: #333; font-weight: bold; margin: 0; line-height: 1.6;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;너는 나처럼 살지 않았으면 좋겠다.&quot;&lt;br /&gt;&quot;어디서든 당당하게 살아라.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무뚝뚝하게 내뱉으셨던 그 말씀이 이제는 유언처럼 가슴에 박혔습니다. 당신처럼 술에 기대어 무너지는 삶이 아니라, 고개를 들고 세상 앞에 당당히 서기를 바랐던 그 마음. 당신은 당신의 삶을 통해 제게 '어떻게 살아야 하는지'를 온몸으로 말씀하고 계셨던 것인지도 모르겠습니다.&lt;/p&gt;
&lt;h2 style=&quot;font-size: 1.3em; color: #222; margin-top: 50px;&quot; data-ke-size=&quot;size26&quot;&gt;연말의 빈자리, 익숙해지지 않는 공허함&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거리에는 벌써 연말 분위기가 가득합니다. 가족들과 웃으며 걷는 사람들을 보면, 당신의 빈자리가 왜 이렇게 시리도록 차갑게 느껴지는지 모르겠습니다. 평생을 이런 외로움과 공허함 속에 살아와서 이제는 익숙해질 법도 한데, 이번 12월은 유독 씁쓸하고 힘이 듭니다.&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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdDnR8/dJMcaiu7qp5/5Cf5YMQbiVsS2NTsHOyMn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdDnR8/dJMcaiu7qp5/5Cf5YMQbiVsS2NTsHOyMn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdDnR8/dJMcaiu7qp5/5Cf5YMQbiVsS2NTsHOyMn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdDnR8%2FdJMcaiu7qp5%2F5Cf5YMQbiVsS2NTsHOyMn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/cw6f2xxFSmo?si=PZubzG27NKdnB15M&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;div style=&quot;margin-top: 60px; padding: 30px; border-radius: 10px; background: linear-gradient(to right, #f4f4f4, #fff); border: 1px solid #eee;&quot;&gt;
&lt;p style=&quot;margin: 0; font-size: 1.05em; color: #444;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아버지, 이제 이곳에서의 모든 미련과 나빴던 기억은 다 털어버리세요.&lt;/b&gt;&lt;br /&gt;술기운 없이 맑은 정신으로, 아프지 않은 다리로 저 하늘을 마음껏 누비시길 바랍니다. 제가 이 공허함을 이겨내고 당당하게 살아가는 것이, 이미 떠난 아버지의 짐을 덜어드리는 길임을 잊지 않겠습니다.&lt;br /&gt;&lt;br /&gt;고생 많으셨습니다. 이제는 부디, 편히 쉬세요.&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;margin-top: 50px; text-align: right; color: #888;&quot; data-ke-size=&quot;size16&quot;&gt;2025년 12월 24일&lt;br /&gt;못다 한 사랑을 담아, 아들이 올림&lt;/p&gt;
&lt;/div&gt;</description>
      <category>DailyRoutine</category>
      <category>무빈소장례</category>
      <category>부모님</category>
      <category>사부곡</category>
      <category>삼가고인의명복을빕니다</category>
      <category>아버지</category>
      <category>아버지의부고</category>
      <category>어린시절기억</category>
      <category>울산</category>
      <category>추모</category>
      <category>추모편지</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/565</guid>
      <comments>https://odinbox.tistory.com/565#entry565comment</comments>
      <pubDate>Wed, 24 Dec 2025 20:16:59 +0900</pubDate>
    </item>
    <item>
      <title>NVIDIA, 네모트론 엘라스틱(Nemotron Elastic) 분석</title>
      <link>https://odinbox.tistory.com/564</link>
      <description>&lt;div style=&quot;font-family: 'Pretendard', 'Malgun Gothic', sans-serif; line-height: 1.8; color: #333; max-width: 900px; margin: 0 auto; padding: 30px; border: 1px solid #e1e1e1; border-radius: 12px; background-color: #ffffff;&quot;&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 50px;&quot;&gt;
&lt;p style=&quot;color: #0070f3; font-weight: 600; letter-spacing: 1px; margin-bottom: 10px;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NVIDIA AI RESEARCH DEEP DIVE&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (3).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clEzTr/dJMcagjMjew/03rqkbyQLH6BhmmZDRilk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clEzTr/dJMcagjMjew/03rqkbyQLH6BhmmZDRilk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clEzTr/dJMcagjMjew/03rqkbyQLH6BhmmZDRilk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclEzTr%2FdJMcagjMjew%2F03rqkbyQLH6BhmmZDRilk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (3).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div style=&quot;width: 60px; height: 4px; background-color: #0070f3; margin: 25px auto;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 50px;&quot;&gt;
&lt;h2 style=&quot;font-size: 1.6em; color: #222; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px;&quot; data-ke-size=&quot;size26&quot;&gt;번역 및 분석을 통해 본 AI 모델의 미래&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;엔비디아가 최근 공개한 논문 &lt;b&gt;&quot;Nemotron Elastic: Towards Efficient Many-in-One Reasoning LLMs (arXiv:2511.16664)&quot;&lt;/b&gt;를 한국어로 번역하고, 그 핵심 원리를 심층 분석한 결과물입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;기존의 인공지능 개발 방식은 커다란 모델(예: 12B)과 작은 모델(예: 6B)을 만들 때 각각 수조 개의 데이터를 사용해 따로 학습시켜야 했습니다. 이는 비용과 시간 면에서 엄청난 낭비를 초래합니다. 엔비디아의 연구진은 이러한 문제를 해결하기 위해, &lt;b&gt;'단 한 번의 학습으로 여러 크기의 모델을 즉시 추출'&lt;/b&gt;할 수 있는 '엘라스틱(Elastic)' 아키텍처를 제안했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 50px;&quot;&gt;
&lt;h2 style=&quot;font-size: 1.6em; color: #222; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px;&quot; data-ke-size=&quot;size26&quot;&gt;왜 '엘라스틱(Elastic)'인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;엘라스틱(Elastic)은 '탄력 있는'이라는 뜻입니다. 이 모델은 필요에 따라 크기를 자유자재로 줄였다 늘렸다 할 수 있습니다. 이를 가능하게 하는 핵심 원리는 &lt;b&gt;가중치 공유(Weight Sharing)&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;padding-left: 20px;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;margin-bottom: 15px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;구조적 유연성:&lt;/b&gt; 부모 모델인 12B 모델의 신경망 중 일부를 선택적으로 사용함으로써 별도의 추가 학습 없이 9B나 6B 모델을 즉시 만들어냅니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;margin-bottom: 15px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;지식 증류 기반 학습:&lt;/b&gt; 학습 과정에서 가장 큰 모델이 스승 역할을 하고, 추출될 작은 모델들이 그 지식을 실시간으로 전수받는 '지식 증류' 기법을 적용하여 작은 모델의 성능 하락을 방어합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 50px;&quot;&gt;
&lt;h2 style=&quot;font-size: 1.6em; color: #222; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px;&quot; data-ke-size=&quot;size26&quot;&gt;네모트론 엘라스틱만의 3가지 핵심 기술&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. MSE 기반의 정밀한 레이어 선별&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;단순히 레이어를 무작위로 제거하는 것이 아닙니다. 전체 모델의 결과값과 특정 레이어를 뺐을 때의 오차(Mean Squared Error)를 계산합니다. 오차가 가장 적은, 즉 &lt;b&gt;성능에 영향이 적은 레이어부터 순차적으로 제거&lt;/b&gt;함으로써 작은 모델의 정확도를 극대화했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 맘바와 어텐션의 하이브리드 설계&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;네모트론 엘라스틱은 문맥 파악이 뛰어난 '어텐션(Attention)'과 연산 효율이 좋은 '맘바(Mamba)' 구조를 섞었습니다. 이 덕분에 긴 문장을 읽을 때 메모리를 적게 쓰면서도 복잡한 논리 문제를 잘 풀 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 2단계 커리큘럼 및 49K 롱컨텍스트 학습&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;모델의 '추론 능력'을 위해 두 단계로 학습합니다. 특히 2단계에서는 &lt;b&gt;49,000개 이상의 토큰(단어 조각)을 한 번에 처리&lt;/b&gt;하는 긴 문맥 학습을 진행하여, AI가 복잡한 수학 문제나 코딩 문제를 끝까지 논리적으로 풀 수 있게 만들었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 50px;&quot;&gt;
&lt;h2 style=&quot;font-size: 1.6em; color: #222; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px;&quot; data-ke-size=&quot;size26&quot;&gt;데이터로 증명된 효율성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;네모트론 엘라스틱은 경제성과 성능 두 가지 측면에서 혁신적인 수치를 기록했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;width: 100%; border-collapse: collapse; margin-top: 20px; border-top: 2px solid #333;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;
&lt;th style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;지표 항목&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 모델 개발 방식&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;padding: 15px; border-bottom: 1px solid #ddd; color: #0070f3;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;네모트론 엘라스틱&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd; font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;학습 비용(토큰)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;수 조 개의 토큰 소모&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단 1,100억 개(110B)로 해결&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd; font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비용 절감율&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1.0x (기준)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd; font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;약 360배 절감&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd; font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;성능 유지&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;별도 최적화 필요&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;padding: 15px; border-bottom: 1px solid #ddd;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 독립 모델과 대등한 점수&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 50px;&quot;&gt;
&lt;h2 style=&quot;font-size: 1.6em; color: #222; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px;&quot; data-ke-size=&quot;size26&quot;&gt;참고 자료 및 원문 정보&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;상세한 수식과 실험 결과는 아래 공식 논문을 통해 확인하실 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #f0f7ff; padding: 15px; border-radius: 8px;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;원문 논문:&lt;/b&gt; &lt;a style=&quot;color: #0070f3; text-decoration: none;&quot; href=&quot;https://arxiv.org/abs/2511.16664&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Nemotron Elastic: Towards Efficient Many-in-One Reasoning LLMs&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #f0f7ff; padding: 15px; border-radius: 8px;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;참조 모델:&lt;/b&gt; NVIDIA Nemotron Nano V2 12B&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;padding: 35px; background-color: #1a1a1a; border-radius: 12px; color: #efefef;&quot;&gt;
&lt;h2 style=&quot;margin-top: 0; color: #ffffff; font-size: 1.8em;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;마무리&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #ffffff;&quot;&gt;네모트론 엘라스틱은 인공지능 모델의 '크기'가 더 이상 성능의 유일한 척도가 아님을 보여줍니다. 상황에 따라 모델의 자원을 조절하여 효율적으로 사용하는 이 기술은 클라우드 서버뿐만 아니라 개인용 스마트폰이나 PC에서도 고성능 AI를 원활하게 구동하는 밑거름이 될 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 0;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #ffffff;&quot;&gt;단 한 번의 학습으로 모든 가능성을 여는 엔비디아의 시도가 AI 상용화에 어떠한 가속도를 붙일지 기대됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>IT</category>
      <category>Ai</category>
      <category>LLM</category>
      <category>NVIDIA Nemotron Elastic 분석</category>
      <category>네모트론 엘라스틱 성능</category>
      <category>딥러닝연구</category>
      <category>맘바 아키텍처 원리</category>
      <category>모델 압축 기술 MSE</category>
      <category>엔비디아 AI 신기술</category>
      <category>온디바이스 AI</category>
      <category>인공지능</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/564</guid>
      <comments>https://odinbox.tistory.com/564#entry564comment</comments>
      <pubDate>Sat, 20 Dec 2025 16:34:04 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL 파이썬 연동방법</title>
      <link>https://odinbox.tistory.com/563</link>
      <description>&lt;div&gt;
&lt;style&gt;
    :root {
        --pp-bg-color: #ffffff;
        --pp-text-color: #333333;
        --pp-title-color: #2c3e50;
        --pp-accent-color: #336791;
        --pp-sub-bg: #f8f9fa;
        --pp-border-color: #e9ecef;
        --pp-code-bg: #282c34;
        --pp-code-text: #abb2bf;
        --pp-note-bg: #f0f7fb;
        --pp-note-border: #cce5ff;
        --pp-tag-bg: #f1f3f5;
        --pp-tag-text: #495057;
    }

    @media (prefers-color-scheme: dark) {
        :root {
            --pp-bg-color: #1e1e1e;
            --pp-text-color: #e0e0e0;
            --pp-title-color: #ffffff;
            --pp-accent-color: #61afef;
            --pp-sub-bg: #2d2d2d;
            --pp-border-color: #444444;
            --pp-code-bg: #121212;
            --pp-code-text: #dcdcdc;
            --pp-note-bg: #2a3b4c;
            --pp-note-border: #336791;
            --pp-tag-bg: #333333;
            --pp-tag-text: #cccccc;
        }
    }

    #postgrespython_container {
        font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
        line-height: 1.8;
        color: var(--pp-text-color);
        background-color: var(--pp-bg-color);
        max-width: 860px;
        margin: 0 auto;
        padding: 20px;
        box-sizing: border-box;
        word-break: keep-all;
    }

    @keyframes postgrespython_fadeInUp {
        from { opacity: 0; transform: translateY(20px); }
        to { opacity: 1; transform: translateY(0); }
    }

    .postgrespython_section {
        margin-bottom: 60px;
        opacity: 0;
        animation: postgrespython_fadeInUp 0.6s ease-out forwards;
    }
    .postgrespython_section:nth-child(2) { animation-delay: 0.1s; }
    .postgrespython_section:nth-child(3) { animation-delay: 0.2s; }
    .postgrespython_section:nth-child(4) { animation-delay: 0.3s; }
    .postgrespython_section:nth-child(5) { animation-delay: 0.4s; }

    .postgrespython_title {
        font-size: 2.2rem;
        font-weight: 800;
        color: var(--pp-title-color);
        border-bottom: 3px solid var(--pp-accent-color);
        padding-bottom: 20px;
        margin-bottom: 40px;
        line-height: 1.3;
    }

    .postgrespython_subtitle {
        font-size: 1.5rem;
        font-weight: 700;
        color: var(--pp-accent-color);
        margin-top: 50px;
        margin-bottom: 20px;
        padding-left: 15px;
        border-left: 5px solid var(--pp-accent-color);
    }

    .postgrespython_text {
        font-size: 1.05rem;
        margin-bottom: 20px;
        text-align: justify;
    }

    .postgrespython_note {
        background-color: var(--pp-note-bg);
        border: 1px solid var(--pp-note-border);
        padding: 20px;
        border-radius: 8px;
        margin: 25px 0;
    }
    .postgrespython_note strong {
        color: var(--pp-accent-color);
        display: block;
        margin-bottom: 10px;
        font-size: 1.1rem;
    }

    .postgrespython_code_wrapper {
        position: relative;
        margin: 30px 0;
    }

    .postgrespython_code_block {
        background-color: var(--pp-code-bg);
        color: var(--pp-code-text);
        padding: 20px;
        padding-top: 40px;
        border-radius: 8px;
        font-family: 'Consolas', 'Monaco', monospace;
        font-size: 0.95rem;
        overflow-x: auto;
        line-height: 1.6;
        border: 1px solid var(--pp-border-color);
        white-space: pre;
    }

    .postgrespython_copy_btn {
        position: absolute;
        top: 10px;
        right: 10px;
        background-color: #4a4a4a;
        color: #fff;
        border: none;
        border-radius: 4px;
        padding: 5px 12px;
        font-size: 0.8rem;
        cursor: pointer;
        transition: all 0.2s;
        z-index: 10;
        font-family: sans-serif;
    }
    .postgrespython_copy_btn:hover {
        background-color: var(--pp-accent-color);
    }

    .postgrespython_code_keyword { color: #c678dd; font-weight: bold; }
    .postgrespython_code_func { color: #61afef; }
    .postgrespython_code_string { color: #98c379; }

    .postgrespython_example_label {
        display: inline-block;
        background-color: var(--pp-accent-color);
        color: #fff;
        padding: 6px 16px;
        border-radius: 20px;
        font-weight: bold;
        font-size: 0.95rem;
        margin-bottom: 15px;
        margin-top: 30px;
    }

    .postgrespython_thumbnail_area {
        margin-bottom: 40px;
        text-align: center;
    }
    .postgrespython_thumbnail_area img {
        max-width: 100%;
        height: auto;
        border-radius: 12px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    }

    .postgrespython_list { margin-left: 20px; margin-bottom: 20px; }
    .postgrespython_list li { margin-bottom: 10px; }

    .postgrespython_tag_container {
        margin-top: 80px;
        padding-top: 30px;
        border-top: 1px solid var(--pp-border-color);
    }
    .postgrespython_tag_item {
        background-color: var(--pp-tag-bg);
        color: var(--pp-tag-text);
        padding: 8px 15px;
        border-radius: 20px;
        font-size: 0.9rem;
        margin-right: 8px;
        margin-bottom: 8px;
        display: inline-block;
        text-decoration: none;
        transition: background-color 0.2s;
    }
    .postgrespython_tag_item:hover {
        background-color: var(--pp-accent-color);
        color: #fff;
    }
    .postgrespython_hidden_tags { display: none; }

    @media (max-width: 768px) {
        #postgrespython_container { padding: 15px; }
        .postgrespython_title { font-size: 1.8rem; }
        .postgrespython_subtitle { font-size: 1.3rem; margin-top: 30px; }
        .postgrespython_code_block { font-size: 0.85rem; padding: 15px; padding-top: 40px; }
    }
&lt;/style&gt;
&lt;/div&gt;
&lt;div id=&quot;postgrespython_container&quot;&gt;
&lt;div class=&quot;postgrespython_section&quot;&gt;
&lt;div class=&quot;postgrespython_thumbnail_area&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZUCEi/dJMcaiV6dtf/nVwxSMkS45CZ4t0wXLRRbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZUCEi/dJMcaiV6dtf/nVwxSMkS45CZ4t0wXLRRbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZUCEi/dJMcaiV6dtf/nVwxSMkS45CZ4t0wXLRRbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZUCEi%2FdJMcaiV6dtf%2FnVwxSMkS45CZ4t0wXLRRbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespython_section&quot;&gt;
&lt;h2 class=&quot;postgrespython_subtitle&quot; data-ke-size=&quot;size26&quot;&gt;들어가며 : SQL의 한계를 넘어서&lt;/h2&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL은 강력한 관계형 데이터베이스이지만 순수 SQL만으로는 복잡한 비즈니스 로직이나 문자열 처리를 구현하는 데 한계가 있습니다. 이때 사용할 수 있는 가장 강력한 도구가 바로 PL/Python입니다. 이는 데이터베이스 내부에서 파이썬 언어를 사용하여 함수나 프로시저를 작성할 수 있게 해주는 절차적 언어 핸들러입니다. 본 글에서는 윈도우 운영체제에서 PL/Python을 사용하기 위한 설치 방법과 환경 설정 그리고 실무에서 활용 가능한 예제 코드를 상세하게 정리해 드립니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespython_section&quot;&gt;
&lt;h2 class=&quot;postgrespython_subtitle&quot; data-ke-size=&quot;size26&quot;&gt;윈도우 환경 설치 및 설정 방법&lt;/h2&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;윈도우에서 PostgreSQL과 파이썬을 연동할 때 가장 주의해야 할 점은 버전 호환성입니다. 리눅스 패키지 관리자와 달리 윈도우 인스톨러는 특정 파이썬 버전에 의존적인 DLL 파일을 포함하고 있습니다.&lt;/p&gt;
&lt;div class=&quot;postgrespython_note&quot;&gt;&lt;b&gt;핵심 : 파이썬 버전 일치시키기&lt;/b&gt; 반드시 PostgreSQL 설치 폴더 내의 bin 디렉터리에 있는 plpython3.dll 파일이 요구하는 파이썬 버전을 설치해야 합니다. 버전이 다르면 함수 생성 시 라이브러리를 로드할 수 없다는 오류가 발생합니다.&lt;/div&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;설치 및 설정 단계는 다음과 같습니다.&lt;/p&gt;
&lt;ul class=&quot;postgrespython_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Python 설치 : &lt;/b&gt; PostgreSQL 버전에 맞는 파이썬을 공식 홈페이지에서 다운로드하여 설치합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;환경 변수 설정 : &lt;/b&gt; 제어판의 시스템 환경 변수 설정에서 PYTHONHOME 변수를 새로 만들고 파이썬 설치 경로를 지정해야 합니다. 또한 Path 변수에도 파이썬 실행 경로와 Scripts 경로를 추가합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서비스 재시작 : &lt;/b&gt; 환경 변수 변경 사항이 PostgreSQL 서비스에 적용되도록 Windows 서비스 관리자에서 서비스를 재시작합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespython_section&quot;&gt;
&lt;h2 class=&quot;postgrespython_subtitle&quot; data-ke-size=&quot;size26&quot;&gt;PostgreSQL 확장 활성화&lt;/h2&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;환경 설정이 끝났다면 데이터베이스에 접속하여 확장을 생성해야 합니다. plpython3u 확장을 설치하며 여기서 u는 untrusted를 의미하므로 슈퍼유저 권한이 필요합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespython_code_wrapper&quot;&gt;&lt;button class=&quot;postgrespython_copy_btn&quot;&gt;복사&lt;/button&gt;
&lt;pre class=&quot;postgrespython_code_block pgsql&quot;&gt;&lt;code&gt;CREATE EXTENSION plpython3u;

SELECT * FROM pg_extension WHERE extname = 'plpython3u';&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespython_section&quot;&gt;
&lt;h2 class=&quot;postgrespython_subtitle&quot; data-ke-size=&quot;size26&quot;&gt;PL/Python 함수 활용 예제&lt;/h2&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;파이썬 문법을 그대로 사용하여 DB 함수를 만드는 방법을 예제와 함께 살펴보겠습니다.&lt;/p&gt;
&lt;span class=&quot;postgrespython_example_label&quot;&gt;예제 1 : 두 수 비교 함수&lt;/span&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;가장 기초적인 형태의 함수입니다. 파이썬의 if 조건문을 사용하여 로직을 구현합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespython_code_wrapper&quot;&gt;&lt;button class=&quot;postgrespython_copy_btn&quot;&gt;복사&lt;/button&gt;
&lt;pre class=&quot;postgrespython_code_block pgsql&quot;&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION public.py_max(a integer, b integer)
RETURNS integer
AS $$
  if a &amp;gt; b : 
      return a
  return b
$$ LANGUAGE plpython3u;

SELECT public.py_max(10, 20);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span class=&quot;postgrespython_example_label&quot;&gt;예제 2 : JSON 데이터 처리&lt;/span&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;파이썬의 내장 모듈인 json을 import하여 딕셔너리 데이터를 손쉽게 JSON 문자열로 변환할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;postgrespython_code_wrapper&quot;&gt;&lt;button class=&quot;postgrespython_copy_btn&quot;&gt;복사&lt;/button&gt;
&lt;pre class=&quot;postgrespython_code_block sql&quot;&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION public.py_create_json(key text, value text)
RETURNS json
AS $$
  import json
  data = {key :  value}
  return json.dumps(data)
$$ LANGUAGE plpython3u;

SELECT public.py_create_json('result', 'success');&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span class=&quot;postgrespython_example_label&quot;&gt;예제 3 : 집합 결과 반환 (SETOF)&lt;/span&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;여러 행을 반환해야 하는 경우 파이썬의 yield 키워드를 사용하여 제너레이터 형태로 구현합니다.&lt;/p&gt;
&lt;div class=&quot;postgrespython_code_wrapper&quot;&gt;&lt;button class=&quot;postgrespython_copy_btn&quot;&gt;복사&lt;/button&gt;
&lt;pre class=&quot;postgrespython_code_block pgsql&quot;&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION public.py_sequence(start_val int, end_val int)
RETURNS SETOF integer
AS $$
  for i in range(start_val, end_val + 1) : 
      yield i
$$ LANGUAGE plpython3u;

SELECT * FROM public.py_sequence(1, 5);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespython_section&quot;&gt;
&lt;h2 class=&quot;postgrespython_subtitle&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p class=&quot;postgrespython_text&quot; data-ke-size=&quot;size16&quot;&gt;이상으로 윈도우 환경에서 PostgreSQL에 파이썬을 연동하고 활용하는 방법에 대해 알아보았습니다. PL/Python을 도입하면 복잡한 연산이나 외부 라이브러리가 필요한 작업을 데이터베이스 계층에서 효율적으로 처리할 수 있습니다. 개발 환경 구축 시 파이썬 버전과 환경 변수 설정만 꼼꼼히 챙기신다면 강력한 백엔드 기능을 구현하실 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;postgrespython_section postgrespython_tag_container&quot;&gt;
&lt;div&gt;&lt;span class=&quot;postgrespython_tag_item&quot;&gt;#PostgreSQL&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#Python&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#PLPython&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#윈도우설정&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#데이터베이스&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#백엔드&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#DB함수&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#SQL튜닝&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#개발자가이드&lt;/span&gt; &lt;span class=&quot;postgrespython_tag_item&quot;&gt;#프로시저&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;postgrespython_hidden_tags&quot;&gt;포스트그레스큐엘 파이썬 연동, plpython3u 설치 방법, 윈도우 Postgres 확장, DB 파이썬 프로시저, PostgreSQL Python Extension, 데이터베이스 튜닝, SQL 파이썬 함수, PostgreSQL 예제, 백엔드 개발 팁, 윈도우 서버 DB 설정&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
    function postgrespython_copy(button) {
        var codeBlock = button.nextElementSibling.innerText;
        navigator.clipboard.writeText(codeBlock).then(function() {
            var originalText = button.innerText;
            button.innerText = '완료';
            button.style.backgroundColor = '#2ecc71';
            setTimeout(function() {
                button.innerText = originalText;
                button.style.backgroundColor = ''; 
            }, 2000);
        }).catch(function(err) {
            alert('복사에 실패했습니다.');
        });
    }
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>db함수</category>
      <category>PLPython</category>
      <category>PostgreSQL</category>
      <category>python</category>
      <category>SQL튜닝</category>
      <category>개발자가이드</category>
      <category>데이터베이스</category>
      <category>백엔드</category>
      <category>윈도우서버</category>
      <category>저장프로시저</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/563</guid>
      <comments>https://odinbox.tistory.com/563#entry563comment</comments>
      <pubDate>Wed, 10 Dec 2025 21:03:24 +0900</pubDate>
    </item>
    <item>
      <title>Oracle &amp;amp; PostgreSQL, SMTP 관련 가이드</title>
      <link>https://odinbox.tistory.com/562</link>
      <description>&lt;div&gt;
&lt;style&gt;
    /* 1. 전체 레이아웃 (전문 기술 문서 스타일) */
    #odin_wrap {
        font-family: 'Pretendard', 'Apple SD Gothic Neo', 'Noto Sans KR', sans-serif;
        color: #212529;
        line-height: 1.8;
        max-width: 860px;
        margin: 0 auto;
        word-break: keep-all;
        letter-spacing: -0.02em;
    }

    /* 2. 썸네일 이미지 스타일 */
    .odin_thumb_box {
        text-align: center;
        margin-bottom: 60px;
        border-radius: 8px;
        overflow: hidden;
        border: 1px solid #e0e0e0;
        box-shadow: 0 4px 12px rgba(0,0,0,0.05);
    }
    .odin_thumb_box img {
        max-width: 100%;
        height: auto;
        display: block;
    }

    /* 3. 타이포그래피 (TOC 호환성 고려) */
    .odin_section {
        margin-bottom: 80px;
    }

    /* H1: 글 제목과 유사한 스타일 (본문 내 강조) */
    .odin_title {
        font-size: 2.2rem;
        font-weight: 800;
        color: #111;
        border-bottom: 3px solid #0056b3;
        padding-bottom: 20px;
        margin-bottom: 40px;
    }

    /* H2: 대주제 - 자동 목차 수집 대상 */
    .odin_h2 {
        font-size: 1.7rem;
        font-weight: 700;
        color: #0056b3; /* 신뢰감을 주는 딥 블루 */
        border-left: 5px solid #0056b3;
        padding-left: 15px;
        margin-top: 60px;
        margin-bottom: 25px;
        background-color: #f8f9fa; /* 연한 회색 배경으로 영역 구분 */
        padding-top: 12px;
        padding-bottom: 12px;
    }

    /* H3: 소주제 - 자동 목차 수집 대상 */
    .odin_h3 {
        font-size: 1.35rem;
        font-weight: 600;
        color: #333;
        margin-top: 40px;
        margin-bottom: 15px;
        border-bottom: 1px solid #dee2e6;
        padding-bottom: 10px;
        display: block;
    }

    .odin_p {
        font-size: 1.05rem;
        color: #495057;
        margin-bottom: 15px;
        text-align: justify;
    }

    /* 4. 코드 블록 디자인 (High Contrast Dark Theme) */
    .odin_code_wrap {
        background-color: #1e1e1e; /* 짙은 배경색 */
        border-radius: 6px;
        box-shadow: 0 10px 25px rgba(0,0,0,0.3); /* 깊이감 있는 그림자 */
        margin: 30px 0;
        overflow: hidden;
        border: 1px solid #333;
    }

    .odin_code_header {
        background-color: #252526;
        padding: 8px 15px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid #3e3e42;
    }

    .odin_filename {
        color: #cccccc;
        font-size: 0.9rem;
        font-family: 'Consolas', monospace;
        font-weight: 500;
    }

    .odin_copy_btn {
        background-color: #0e639c;
        color: white;
        border: none;
        padding: 5px 12px;
        border-radius: 2px;
        font-size: 0.8rem;
        cursor: pointer;
        font-family: sans-serif;
        transition: background 0.2s;
    }
    .odin_copy_btn:hover { background-color: #1177bb; }
    .odin_copy_btn.copied { background-color: #198754; }

    .odin_pre {
        margin: 0;
        padding: 20px;
        overflow-x: auto;
        font-family: 'Consolas', 'Monaco', 'D2Coding', monospace; /* 가독성 좋은 코딩 폰트 */
        font-size: 0.95rem;
        line-height: 1.6;
        color: #d4d4d4; /* 기본 텍스트 색상 (밝은 회색) */
        background-color: #1e1e1e; /* 코드 영역 배경 (Dark) */
    }

    /* 문법 하이라이팅 (선명한 색상 적용) */
    .kwd { color: #569cd6; font-weight: bold; } /* 키워드 (Blue) */
    .func { color: #dcdcaa; } /* 함수 (Yellow) */
    .str { color: #ce9178; } /* 문자열 (Orange) */
    .num { color: #b5cea8; } /* 숫자 (Light Green) */
    .typ { color: #4ec9b0; } /* 타입 (Teal) */
    .cmt { color: #6a9955; font-style: italic; } /* 주석 (Green) */
    .var { color: #9cdcfe; } /* 변수 (Light Blue) */

    /* 5. 기술 상세 설명 박스 */
    .odin_detail_box {
        background-color: #ffffff;
        border: 1px solid #ced4da;
        border-left: 5px solid #6c757d;
        padding: 20px;
        margin: 20px 0;
    }
    .odin_detail_title {
        font-weight: 700;
        font-size: 1.05rem;
        color: #343a40;
        margin-bottom: 8px;
        display: block;
        text-transform: uppercase;
    }

    /* 6. 문제 해결 (Troubleshooting) 영역 */
    .odin_trouble_wrap {
        background-color: #fff5f5; /* 아주 연한 붉은 배경 */
        border: 1px solid #ffc9c9;
        border-radius: 6px;
        padding: 25px;
        margin-top: 40px;
    }
    .odin_trouble_head {
        font-size: 1.2rem;
        font-weight: 800;
        color: #c92a2a;
        margin-bottom: 20px;
        display: block;
        border-bottom: 2px solid #ffec99;
        padding-bottom: 10px;
    }
    .odin_trouble_item {
        margin-bottom: 20px;
    }
    .odin_err_code {
        display: inline-block;
        background-color: #e03131;
        color: #fff;
        padding: 2px 8px;
        border-radius: 4px;
        font-weight: bold;
        font-size: 0.9rem;
        font-family: monospace;
        margin-right: 8px;
    }
    .odin_err_desc {
        display: block;
        margin-top: 5px;
        color: #495057;
        font-size: 1rem;
    }

&lt;/style&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
    function copyOdinCode(elementId, btnId) {
        var codeElement = document.getElementById(elementId);
        var textToCopy = codeElement.innerText;
        var tempTextArea = document.createElement(&quot;textarea&quot;);
        tempTextArea.value = textToCopy;
        document.body.appendChild(tempTextArea);
        tempTextArea.select();
        document.execCommand(&quot;copy&quot;);
        document.body.removeChild(tempTextArea);

        var btn = document.getElementById(btnId);
        var originalText = btn.innerText;
        btn.innerText = &quot;복사됨&quot;;
        btn.classList.add(&quot;copied&quot;);

        setTimeout(function() {
            btn.innerText = originalText;
            btn.classList.remove(&quot;copied&quot;);
        }, 2000);
    }
&lt;/script&gt;
&lt;/p&gt;
&lt;div id=&quot;odin_wrap&quot;&gt;
&lt;div class=&quot;odin_thumb_box&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOwtoI/dJMcafykeF3/kebJzeAGcJ4u6lLNZktKz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOwtoI/dJMcafykeF3/kebJzeAGcJ4u6lLNZktKz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOwtoI/dJMcafykeF3/kebJzeAGcJ4u6lLNZktKz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOwtoI%2FdJMcafykeF3%2FkebJzeAGcJ4u6lLNZktKz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;odin_section&quot;&gt;
&lt;h1 class=&quot;odin_title&quot;&gt;Oracle vs PostgreSQL 가이드&lt;/h1&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;시스템 운영 환경에서 데이터베이스가 직접 이메일을 발송해야 하는 요구사항은 꾸준히 존재합니다. 배치 작업 결과의 즉각적인 보고나 치명적인 데이터 오류 발생 시 관리자 알림을 위해, WAS(Web Application Server)를 거치지 않고 DB 레벨에서 SMTP 프로토콜을 직접 제어하는 것이 효율적일 때가 많습니다.&lt;/p&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;본 문서에서는 엔터프라이즈의 표준인 Oracle의 &lt;code&gt;UTL_SMTP&lt;/code&gt; 방식과 오픈소스의 강자 PostgreSQL의 &lt;code&gt;PL/Python&lt;/code&gt; 구현 방식을 비교 분석하고, 실무 적용 시 반드시 마주하게 되는 보안 설정 및 오류 해결 방법까지 상세히 기술합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;odin_section&quot;&gt;
&lt;h2 class=&quot;odin_h2&quot; data-ke-size=&quot;size26&quot;&gt;1. Oracle : UTL_SMTP 패키지 활용 및 ACL 보안&lt;/h2&gt;
&lt;div class=&quot;odin_detail_box&quot;&gt;&lt;span class=&quot;odin_detail_title&quot;&gt;Technical Context&lt;/span&gt;
&lt;p class=&quot;odin_p&quot; style=&quot;margin-bottom: 0;&quot; data-ke-size=&quot;size16&quot;&gt;Oracle 11g R2 버전 이후부터는 데이터베이스의 보안 강화 정책에 따라, 외부 네트워크(TCP/IP)로 나가는 패킷을 엄격히 통제합니다. 따라서 SMTP 서버와 통신하기 위해서는 반드시 &lt;b&gt;ACL(Access Control List)&lt;/b&gt;을 생성하여 특정 유저에게 &lt;code&gt;Resolve&lt;/code&gt; 및 &lt;code&gt;Connect&lt;/code&gt; 권한을 부여해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class=&quot;odin_h3&quot; data-ke-size=&quot;size23&quot;&gt;Step 1. ACL(Access Control List) 권한 부여 (SYSDBA)&lt;/h3&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;가장 먼저 수행해야 할 작업은 네트워크 통신을 위한 화이트리스트 등록입니다. 이 작업은 SYS 계정에서 수행해야 합니다.&lt;/p&gt;
&lt;div class=&quot;odin_code_wrap&quot;&gt;
&lt;div class=&quot;odin_code_header&quot;&gt;&lt;span class=&quot;odin_filename&quot;&gt;oracle_acl_setup.sql&lt;/span&gt; &lt;button id=&quot;btn_acl&quot; class=&quot;odin_copy_btn&quot;&gt;Code Copy&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;code_acl&quot; class=&quot;odin_pre typescript&quot;&gt;&lt;code&gt;BEGIN
    -- 1. ACL 파일 생성 및 권한 정의
    DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
        acl          =&amp;gt; 'odinbox_smtp_acl.xml',
        description  =&amp;gt; 'OdinBOX SMTP Access',
        principal    =&amp;gt; 'ODIN_USER', -- 권한을 부여할 DB 스키마(유저)명
        is_grant     =&amp;gt; TRUE,
        privilege    =&amp;gt; 'connect'
    );
    
    -- 2. 도메인 해석을 위한 Resolve 권한 추가
    DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE (
        acl          =&amp;gt; 'odinbox_smtp_acl.xml',
        principal    =&amp;gt; 'ODIN_USER',
        is_grant     =&amp;gt; TRUE,
        privilege    =&amp;gt; 'resolve'
    );

    -- 3. 타겟 호스트 및 포트 매핑 (Gmail 예시)
    DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
        acl          =&amp;gt; 'odinbox_smtp_acl.xml',
        host         =&amp;gt; 'smtp.gmail.com',
        lower_port   =&amp;gt; 587,
        upper_port   =&amp;gt; 587
    );
    COMMIT;
END;
/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;odin_h3&quot; data-ke-size=&quot;size23&quot;&gt;Step 2. 메일 발송 프로시저 구현&lt;/h3&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;ACL 설정이 완료되면, UTL_SMTP 패키지를 사용하여 실제 발송 로직을 구현합니다. 한글 깨짐 방지를 위한 헤더 설정과 Base64 인증 처리가 핵심입니다.&lt;/p&gt;
&lt;div class=&quot;odin_code_wrap&quot;&gt;
&lt;div class=&quot;odin_code_header&quot;&gt;&lt;span class=&quot;odin_filename&quot;&gt;oracle_mail_proc.sql&lt;/span&gt; &lt;button id=&quot;btn_ora&quot; class=&quot;odin_copy_btn&quot;&gt;Code Copy&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;code_ora&quot; class=&quot;odin_pre ada&quot;&gt;&lt;code&gt;CREATE OR REPLACE PROCEDURE sp_send_mail_odinbox (
    p_recipient IN VARCHAR2,
    p_subject   IN VARCHAR2,
    p_body      IN VARCHAR2
) IS
    -- [OdinBOX] 변수 선언
    v_conn      UTL_SMTP.CONNECTION;
    v_host      VARCHAR2(50) := 'smtp.gmail.com';
    v_port      NUMBER       := 587; 
    v_user      VARCHAR2(50) := 'helpodinbox@gmail.com'; 
    v_pass      VARCHAR2(50) := 'app_password_key'; -- 앱 비밀번호 사용
BEGIN
    -- 1. TCP 연결 및 Handshake
    v_conn := UTL_SMTP.OPEN_CONNECTION(v_host, v_port);
    UTL_SMTP.HELO(v_conn, v_host);
    UTL_SMTP.STARTTLS(v_conn); -- TLS 보안 세션 시작

    -- 2. SMTP 인증 (AUTH LOGIN 방식 - Base64 인코딩 필수)
    UTL_SMTP.COMMAND(v_conn, 'AUTH LOGIN');
    UTL_SMTP.COMMAND(v_conn, 
        UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(v_user))));
    UTL_SMTP.COMMAND(v_conn, 
        UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(v_pass))));

    -- 3. 데이터 전송 섹션
    UTL_SMTP.MAIL(v_conn, v_user);
    UTL_SMTP.RCPT(v_conn, p_recipient);
    UTL_SMTP.OPEN_DATA(v_conn);
    
    -- [OdinBOX] MIME 헤더 구성 (Subject 한글 처리 중요)
    UTL_SMTP.WRITE_DATA(v_conn, 'Subject: =?UTF-8?B?' || UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(p_subject))) || '?=' || UTL_TCP.CRLF);
    UTL_SMTP.WRITE_DATA(v_conn, 'To: ' || p_recipient || UTL_TCP.CRLF);
    UTL_SMTP.WRITE_DATA(v_conn, 'Content-Type: text/plain; charset=UTF-8' || UTL_TCP.CRLF);
    UTL_SMTP.WRITE_DATA(v_conn, UTL_TCP.CRLF || p_body);
    
    UTL_SMTP.CLOSE_DATA(v_conn);
    UTL_SMTP.QUIT(v_conn);
EXCEPTION
    WHEN OTHERS THEN
        UTL_SMTP.QUIT(v_conn);
        RAISE;
END;
/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;odin_trouble_wrap&quot;&gt;&lt;span class=&quot;odin_trouble_head&quot;&gt;Troubleshooting : Oracle Critical Errors&lt;/span&gt;
&lt;div class=&quot;odin_trouble_item&quot;&gt;&lt;span class=&quot;odin_err_code&quot;&gt;ORA-24247&lt;/span&gt; &lt;span class=&quot;odin_err_desc&quot;&gt; &lt;b&gt;네트워크 접근 권한 거부 (Network Access Denied)&lt;/b&gt;&lt;br /&gt;ACL 설정이 누락되었거나, &lt;code&gt;DBMS_NETWORK_ACL_ADMIN&lt;/code&gt;을 통해 부여된 권한이 현재 접속한 유저와 매핑되지 않았을 때 발생합니다. Step 1의 ACL 스크립트를 재점검하십시오. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;odin_trouble_item&quot;&gt;&lt;span class=&quot;odin_err_code&quot;&gt;ORA-29024&lt;/span&gt; &lt;span class=&quot;odin_err_desc&quot;&gt; &lt;b&gt;인증서 유효성 검사 실패 (Certificate Validation Failure)&lt;/b&gt;&lt;br /&gt;Oracle Wallet에 메일 서버(Gmail 등)의 Root CA 인증서가 등록되지 않았을 때 발생합니다. UTL_SMTP는 기본적으로 SSL/TLS 핸드쉐이크 시 인증서를 검증합니다. 이를 해결하려면 Wallet을 구성하거나, 내부망에 인증서 검증이 없는 SMTP Relay 서버를 구축하여 경유해야 합니다. &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;odin_section&quot;&gt;
&lt;h2 class=&quot;odin_h2&quot; data-ke-size=&quot;size26&quot;&gt;2. PostgreSQL : PL/Python 확장과 유연성&lt;/h2&gt;
&lt;div class=&quot;odin_detail_box&quot;&gt;&lt;span class=&quot;odin_detail_title&quot;&gt;Technical Context&lt;/span&gt;
&lt;p class=&quot;odin_p&quot; style=&quot;margin-bottom: 0;&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL은 모놀리식 구조를 지양하고 &lt;b&gt;Extension(확장)&lt;/b&gt; 생태계를 권장합니다. &lt;code&gt;plpython3u&lt;/code&gt;(Python 3 Untrusted Language) 확장을 설치하면, DB 내부에서 Python의 표준 라이브러리인 &lt;code&gt;smtplib&lt;/code&gt;을 직접 호출할 수 있습니다. 이를 통해 복잡한 인코딩 로직 없이 매우 간결한 코드로 메일 발송이 가능합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class=&quot;odin_h3&quot; data-ke-size=&quot;size23&quot;&gt;Step 1. PL/Python 확장 설치&lt;/h3&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;'Untrusted' 언어는 파일 시스템 접근 등 OS 레벨의 제어가 가능하므로, 오직 &lt;b&gt;Superuser(관리자)&lt;/b&gt; 계정만이 해당 확장을 활성화하고 함수를 생성할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;odin_code_wrap&quot;&gt;
&lt;div class=&quot;odin_code_header&quot;&gt;&lt;span class=&quot;odin_filename&quot;&gt;postgres_ext_setup.sql&lt;/span&gt; &lt;button id=&quot;btn_pg_ext&quot; class=&quot;odin_copy_btn&quot;&gt;Code Copy&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;code_pg_ext&quot; class=&quot;odin_pre pgsql&quot;&gt;&lt;code&gt;-- 사전 조건: DB 서버 OS에 postgresql-contrib 및 python3 패키지가 설치되어 있어야 함
CREATE EXTENSION IF NOT EXISTS plpython3u;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 class=&quot;odin_h3&quot; data-ke-size=&quot;size23&quot;&gt;Step 2. Python smtplib 기반 함수 작성&lt;/h3&gt;
&lt;div class=&quot;odin_code_wrap&quot;&gt;
&lt;div class=&quot;odin_code_header&quot;&gt;&lt;span class=&quot;odin_filename&quot;&gt;postgres_mail_func.sql&lt;/span&gt; &lt;button id=&quot;btn_pg&quot; class=&quot;odin_copy_btn&quot;&gt;Code Copy&lt;/button&gt;&lt;/div&gt;
&lt;pre id=&quot;code_pg&quot; class=&quot;odin_pre pgsql&quot;&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION fn_send_mail_odinbox (
    smtp_to text,
    smtp_subject text,
    smtp_content text
)
RETURNS text
AS $$
    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart

    # [OdinBOX] SMTP 설정
    smtp_host = &quot;smtp.gmail.com&quot;
    smtp_port = 587
    smtp_user = &quot;helpodinbox@gmail.com&quot;
    smtp_pass = &quot;app_password_key&quot;

    # 메시지 컨테이너 생성
    msg = MIMEMultipart()
    msg['From']    = smtp_user
    msg['To']      = smtp_to
    msg['Subject'] = smtp_subject

    # 본문 내용 UTF-8 인코딩 명시
    msg.attach(MIMEText(smtp_content, 'plain', 'utf-8'))

    try:
        # 서버 연결 및 TLS 승격
        server = smtplib.SMTP(smtp_host, smtp_port)
        server.ehlo()
        server.starttls() # 보안 연결 시작
        server.ehlo()
        
        # 로그인 및 발송
        server.login(smtp_user, smtp_pass)
        server.sendmail(smtp_user, smtp_to, msg.as_string())
        server.quit()
        return &quot;Success: Email Sent via OdinBOX&quot;
    except Exception as e:
        # 상세 에러 메시지 반환
        return f&quot;Error: {str(e)}&quot;
$$ LANGUAGE plpython3u;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;odin_trouble_wrap&quot;&gt;&lt;span class=&quot;odin_trouble_head&quot;&gt;Troubleshooting : PostgreSQL Critical Errors&lt;/span&gt;
&lt;div class=&quot;odin_trouble_item&quot;&gt;&lt;span class=&quot;odin_err_code&quot;&gt;ImportError&lt;/span&gt; &lt;span class=&quot;odin_err_desc&quot;&gt; &lt;b&gt;모듈 미설치 오류 (No module named...)&lt;/b&gt;&lt;br /&gt;PostgreSQL의 PL/Python은 DB 서버 OS의 Python 환경을 공유합니다. 만약 라이브러리가 없다는 에러가 발생하면, DB 서버의 쉘(Shell)에서 &lt;code&gt;pip3 install [모듈명]&lt;/code&gt; 명령어를 통해 필요한 패키지를 설치해야 합니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;odin_trouble_item&quot;&gt;&lt;span class=&quot;odin_err_code&quot;&gt;SMTPAuthenticationError&lt;/span&gt; &lt;span class=&quot;odin_err_desc&quot;&gt; &lt;b&gt;인증 실패 (Authentication Failed)&lt;/b&gt;&lt;br /&gt;Google 등 최신 메일 서비스는 보안 수준이 낮은 앱에서의 직접 로그인을 차단합니다. 계정의 일반 비밀번호를 사용하면 이 에러가 발생합니다. 반드시 해당 메일 서비스 설정에서 &lt;b&gt;[2단계 인증]&lt;/b&gt;을 활성화한 후, &lt;b&gt;[앱 비밀번호(App Password)]&lt;/b&gt;를 별도로 생성하여 코드 내 &lt;code&gt;smtp_pass&lt;/code&gt; 변수에 적용해야 합니다. &lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;odin_trouble_item&quot;&gt;&lt;span class=&quot;odin_err_code&quot;&gt;Permission Denied&lt;/span&gt; &lt;span class=&quot;odin_err_desc&quot;&gt; &lt;b&gt;권한 부족 (Superuser Required)&lt;/b&gt;&lt;br /&gt;&lt;code&gt;plpython3u&lt;/code&gt; 언어로 작성된 함수를 생성하거나 수정할 때는 반드시 Superuser 권한이 필요합니다. 일반 유저가 사용해야 한다면, 관리자가 함수를 생성한 뒤 &lt;code&gt;GRANT EXECUTE ON FUNCTION...&lt;/code&gt; 명령어로 실행 권한만 부여하는 방식을 사용하십시오. &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;odin_section&quot;&gt;
&lt;h2 class=&quot;odin_h2&quot; data-ke-size=&quot;size26&quot;&gt;3. 마무리 (Conclusion)&lt;/h2&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;Oracle과 PostgreSQL은 메일 발송이라는 동일한 목적을 달성하기 위해 서로 다른 접근 방식을 취합니다. Oracle은 &lt;code&gt;UTL_SMTP&lt;/code&gt;와 &lt;code&gt;ACL&lt;/code&gt; 설정을 통해 DB 자체의 완결성 있는 기능을 제공하지만, SSL 인증서(Wallet) 관리와 복잡한 인코딩 처리가 진입 장벽이 될 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;반면, PostgreSQL은 Python 생태계를 적극 활용하여 구현 난이도를 대폭 낮추고 코드의 가독성을 높였습니다. 다만, OS 레벨의 패키지 의존성과 Superuser 권한 관리가 필수적이라는 점을 고려해야 합니다. 운영 중인 시스템의 보안 정책과 인프라 환경을 고려하여 가장 적합한 방식을 선택하시기 바랍니다.&lt;/p&gt;
&lt;p class=&quot;odin_p&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>IT</category>
      <category>DBMS_NETWORK_ACL_ADMIN</category>
      <category>DB메일발송</category>
      <category>OdinBOX</category>
      <category>PLPython</category>
      <category>PostgreSQL</category>
      <category>SMTP연동</category>
      <category>UTL_SMTP</category>
      <category>데이터베이스</category>
      <category>백엔드개발</category>
      <category>오라클</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/562</guid>
      <comments>https://odinbox.tistory.com/562#entry562comment</comments>
      <pubDate>Sat, 6 Dec 2025 06:37:09 +0900</pubDate>
    </item>
    <item>
      <title>랜섬웨어(Ransomware)에 대해서 알아보기</title>
      <link>https://odinbox.tistory.com/561</link>
      <description>&lt;div&gt;
&lt;style&gt;
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700;900&amp;display=swap');
    
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    html {
        scroll-behavior: smooth;
    }
    
    .blog-container {
        font-family: 'Noto Sans KR', sans-serif;
        max-width: 1200px;
        margin: 0 auto;
        padding: 40px 20px;
        color: #333;
        line-height: 1.8;
        background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
        animation: backgroundShift 15s ease infinite;
    }
    
    @keyframes backgroundShift {
        0%, 100% { background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); }
        50% { background: linear-gradient(135deg, #e0c3fc 0%, #8ec5fc 100%); }
    }
    
    /* 다크모드 지원 */
    @media (prefers-color-scheme: dark) {
        .blog-container {
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            color: #e0e0e0;
        }
        
        .content-wrapper {
            background: #0f3460 !important;
            color: #e0e0e0;
        }
        
        h1 {
            background: linear-gradient(135deg, #8ec5fc 0%, #e0c3fc 100%) !important;
            -webkit-background-clip: text !important;
            -webkit-text-fill-color: transparent !important;
            background-clip: text !important;
        }
        
        h2 {
            color: #8ec5fc !important;
            border-left-color: #8ec5fc !important;
        }
        
        h3, h4 {
            color: #e0e0e0 !important;
            background: rgba(142, 197, 252, 0.15) !important;
            border-left-color: #8ec5fc !important;
        }
        
        p, li {
            color: #d0d0d0 !important;
        }
        
        .info-box, .warning-box, .intro-box, .reference-box {
            background: rgba(102, 126, 234, 0.2) !important;
            border-left-color: #667eea !important;
        }
        
        .info-box p, .warning-box p, .intro-box p, .reference-box p,
        .info-box li, .warning-box li, .intro-box li, .reference-box li {
            color: #e0e0e0 !important;
        }
        
        .info-box::before, .warning-box::before {
            color: #8ec5fc !important;
        }
        
        .process-step, .prevention-card {
            background: rgba(255, 255, 255, 0.05) !important;
            border-color: #667eea !important;
        }
        
        .process-step h4, .prevention-card h4 {
            color: #8ec5fc !important;
        }
        
        .process-step p, .prevention-card p {
            color: #d0d0d0 !important;
        }
        
        .floating-toc {
            background: rgba(15, 52, 96, 0.95) !important;
            color: #ffffff;
            border: 1px solid rgba(142, 197, 252, 0.3);
        }
        
        .floating-toc h3 {
            color: #8ec5fc !important;
            background: none !important;
            border: none !important;
        }
        
        .floating-toc a {
            color: #b8d4f1 !important;
        }
        
        .floating-toc a:hover {
            background: rgba(142, 197, 252, 0.2) !important;
            color: #8ec5fc !important;
        }
        
        table {
            background: rgba(255, 255, 255, 0.05) !important;
        }
        
        thead {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
        }
        
        tbody tr:hover {
            background: rgba(102, 126, 234, 0.2) !important;
        }
        
        td {
            color: #d0d0d0 !important;
            border-bottom-color: rgba(255, 255, 255, 0.1) !important;
        }
        
        .tag-container {
            background: rgba(255, 255, 255, 0.08) !important;
        }
        
        .tag-title {
            color: #ffffff !important;
        }
        
        .highlight {
            background: rgba(255, 235, 59, 0.3) !important;
            color: #ffeb3b !important;
        }
        
        .meta-info {
            border-bottom-color: rgba(255, 255, 255, 0.1) !important;
        }
        
        .meta-item {
            color: #b0b0b0 !important;
        }
        
        .case-study {
            background: rgba(255, 255, 255, 0.05) !important;
            border-left-color: #f5576c !important;
        }
        
        .case-study h4 {
            color: #f093fb !important;
        }
    }
    
    .content-wrapper {
        background: white;
        padding: 50px;
        border-radius: 20px;
        box-shadow: 0 20px 60px rgba(0,0,0,0.15);
        animation: fadeInUp 1s ease;
        max-width: 900px;
        margin: 0 auto;
    }
    
    @keyframes fadeInUp {
        from {
            opacity: 0;
            transform: translateY(30px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }
    
    .read-time {
        display: inline-block;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 10px 20px;
        border-radius: 50px;
        font-size: 14px;
        font-weight: 500;
        margin-bottom: 20px;
        animation: pulse 2s ease infinite;
    }
    
    @keyframes pulse {
        0%, 100% { transform: scale(1); }
        50% { transform: scale(1.05); }
    }
    
    h1 {
        font-size: 42px;
        font-weight: 900;
        color: #1a1a2e;
        margin-bottom: 30px;
        line-height: 1.3;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
        animation: titleGlow 3s ease infinite;
    }
    
    @keyframes titleGlow {
        0%, 100% { filter: brightness(1); }
        50% { filter: brightness(1.2); }
    }
    
    .meta-info {
        display: flex;
        gap: 20px;
        margin-bottom: 40px;
        padding-bottom: 20px;
        border-bottom: 2px solid #f0f0f0;
        font-size: 14px;
        color: #666;
        flex-wrap: wrap;
    }
    
    .meta-item {
        display: flex;
        align-items: center;
        gap: 8px;
    }
    
    .meta-item::before {
        content: &quot;•&quot;;
        font-size: 16px;
        color: #667eea;
        font-weight: bold;
    }
    
    h2 {
        font-size: 32px;
        font-weight: 700;
        color: #2d3748;
        margin: 50px 0 25px 0;
        padding-left: 20px;
        border-left: 5px solid #667eea;
        animation: slideInLeft 0.8s ease;
        scroll-margin-top: 20px;
    }
    
    @keyframes slideInLeft {
        from {
            opacity: 0;
            transform: translateX(-30px);
        }
        to {
            opacity: 1;
            transform: translateX(0);
        }
    }
    
    h3 {
        font-size: 24px;
        font-weight: 600;
        color: #4a5568;
        margin: 35px 0 20px 0;
        padding: 15px 20px;
        background: linear-gradient(135deg, #f6f8fb 0%, #e9ecf4 100%);
        border-radius: 10px;
        border-left: 4px solid #764ba2;
        transition: all 0.3s ease;
        scroll-margin-top: 20px;
    }
    
    h3:hover {
        transform: translateX(10px);
        box-shadow: 0 5px 15px rgba(0,0,0,0.1);
    }
    
    h4 {
        font-size: 20px;
        font-weight: 700;
        color: #2d3748;
        margin: 25px 0 15px 0;
    }
    
    p {
        font-size: 17px;
        margin-bottom: 20px;
        color: #4a5568;
        text-align: justify;
    }
    
    .intro-box {
        background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
        padding: 30px;
        border-radius: 15px;
        margin: 30px 0;
        border-left: 6px solid #ff6b6b;
        animation: fadeIn 1.5s ease;
    }
    
    @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
    }
    
    .intro-box p {
        font-weight: 500;
        color: #2d3748;
        margin-bottom: 0;
    }
    
    .warning-box {
        background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
        padding: 25px;
        border-radius: 12px;
        margin: 25px 0;
        border-left: 6px solid #dc2626;
        animation: shake 0.5s ease;
    }
    
    @keyframes shake {
        0%, 100% { transform: translateX(0); }
        25% { transform: translateX(-5px); }
        75% { transform: translateX(5px); }
    }
    
    .warning-box::before {
        content: &quot;주의&quot;;
        display: block;
        font-size: 18px;
        font-weight: 700;
        color: #dc2626;
        margin-bottom: 10px;
    }
    
    .info-box {
        background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
        padding: 25px;
        border-radius: 12px;
        margin: 25px 0;
        border-left: 6px solid #3b82f6;
        animation: bounceIn 1s ease;
    }
    
    @keyframes bounceIn {
        0% { transform: scale(0.9); opacity: 0; }
        50% { transform: scale(1.05); }
        100% { transform: scale(1); opacity: 1; }
    }
    
    .info-box::before {
        content: &quot;핵심 정보&quot;;
        display: block;
        font-size: 18px;
        font-weight: 700;
        color: #3b82f6;
        margin-bottom: 10px;
    }
    
    ul, ol {
        margin: 20px 0 20px 20px;
        padding-left: 20px;
    }
    
    li {
        margin-bottom: 15px;
        font-size: 17px;
        color: #4a5568;
        line-height: 1.8;
        position: relative;
        padding-left: 10px;
        animation: fadeInList 0.6s ease forwards;
        opacity: 0;
    }
    
    @keyframes fadeInList {
        to { opacity: 1; }
    }
    
    li:nth-child(1) { animation-delay: 0.1s; }
    li:nth-child(2) { animation-delay: 0.2s; }
    li:nth-child(3) { animation-delay: 0.3s; }
    li:nth-child(4) { animation-delay: 0.4s; }
    li:nth-child(5) { animation-delay: 0.5s; }
    li:nth-child(6) { animation-delay: 0.6s; }
    li:nth-child(7) { animation-delay: 0.7s; }
    li:nth-child(8) { animation-delay: 0.8s; }
    
    ul li::before {
        content: &quot;▸&quot;;
        color: #667eea;
        font-weight: bold;
        position: absolute;
        left: -15px;
    }
    
    .highlight {
        background: linear-gradient(135deg, #fff9c4 0%, #ffeb3b 100%);
        padding: 3px 8px;
        border-radius: 5px;
        font-weight: 600;
        color: #1a1a2e;
    }
    
    .stat-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
        gap: 20px;
        margin: 30px 0;
    }
    
    .stat-card {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        padding: 25px;
        border-radius: 15px;
        color: white;
        text-align: center;
        box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
        transition: all 0.3s ease;
        animation: popIn 0.6s ease;
    }
    
    @keyframes popIn {
        0% { transform: scale(0); opacity: 0; }
        100% { transform: scale(1); opacity: 1; }
    }
    
    .stat-card:hover {
        transform: translateY(-10px) scale(1.05);
        box-shadow: 0 20px 40px rgba(102, 126, 234, 0.5);
    }
    
    .stat-number {
        font-size: 36px;
        font-weight: 900;
        margin-bottom: 10px;
        text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
    }
    
    .stat-label {
        font-size: 16px;
        font-weight: 500;
        opacity: 0.95;
    }
    
    .process-step {
        background: white;
        padding: 25px;
        margin: 20px 0;
        border-radius: 12px;
        border-left: 5px solid #667eea;
        box-shadow: 0 5px 15px rgba(0,0,0,0.08);
        transition: all 0.3s ease;
        animation: slideInRight 0.8s ease;
    }
    
    @keyframes slideInRight {
        from {
            opacity: 0;
            transform: translateX(50px);
        }
        to {
            opacity: 1;
            transform: translateX(0);
        }
    }
    
    .process-step:hover {
        box-shadow: 0 10px 30px rgba(0,0,0,0.15);
        transform: translateX(10px);
    }
    
    .process-step h4 {
        font-size: 20px;
        font-weight: 700;
        color: #667eea;
        margin-bottom: 12px;
    }
    
    .prevention-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
        gap: 25px;
        margin: 30px 0;
    }
    
    .prevention-card {
        background: linear-gradient(135deg, #f6f8fb 0%, #ffffff 100%);
        padding: 30px;
        border-radius: 15px;
        border: 2px solid #e2e8f0;
        transition: all 0.3s ease;
        animation: zoomIn 0.6s ease;
    }
    
    @keyframes zoomIn {
        from {
            transform: scale(0.8);
            opacity: 0;
        }
        to {
            transform: scale(1);
            opacity: 1;
        }
    }
    
    .prevention-card:hover {
        border-color: #667eea;
        box-shadow: 0 15px 35px rgba(102, 126, 234, 0.2);
        transform: translateY(-5px);
    }
    
    .prevention-card h4 {
        font-size: 20px;
        font-weight: 700;
        color: #2d3748;
        margin-bottom: 15px;
    }
    
    .table-container {
        overflow-x: auto;
        margin: 30px 0;
        border-radius: 12px;
        box-shadow: 0 5px 20px rgba(0,0,0,0.1);
    }
    
    table {
        width: 100%;
        border-collapse: collapse;
        background: white;
    }
    
    thead {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
    }
    
    th {
        padding: 18px;
        text-align: left;
        font-weight: 700;
        font-size: 16px;
        border-bottom: 3px solid #5568d3;
    }
    
    td {
        padding: 16px 18px;
        border-bottom: 1px solid #e2e8f0;
        font-size: 16px;
    }
    
    tbody tr {
        transition: all 0.3s ease;
    }
    
    tbody tr:hover {
        background: linear-gradient(135deg, #f6f8fb 0%, #e9ecf4 100%);
        transform: scale(1.02);
    }
    
    .conclusion-box {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 40px;
        border-radius: 15px;
        margin: 40px 0;
        text-align: center;
        box-shadow: 0 15px 40px rgba(102, 126, 234, 0.4);
        animation: fadeInScale 1s ease;
    }
    
    @keyframes fadeInScale {
        from {
            opacity: 0;
            transform: scale(0.9);
        }
        to {
            opacity: 1;
            transform: scale(1);
        }
    }
    
    .conclusion-box h2 {
        color: white;
        border: none;
        padding: 0;
        margin: 0 0 20px 0;
    }
    
    .conclusion-box p {
        color: white;
        font-size: 18px;
        font-weight: 500;
        margin-bottom: 15px;
    }
    
    .tag-container {
        margin: 40px 0 20px 0;
        padding: 25px;
        background: linear-gradient(135deg, #f6f8fb 0%, #e9ecf4 100%);
        border-radius: 12px;
    }
    
    .tag-title {
        font-size: 18px;
        font-weight: 700;
        color: #2d3748;
        margin-bottom: 15px;
    }
    
    .tags {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;
    }
    
    .tag {
        display: inline-block;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 8px 18px;
        border-radius: 25px;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.3s ease;
        cursor: pointer;
        animation: tagPop 0.4s ease;
    }
    
    @keyframes tagPop {
        0% { transform: scale(0); }
        50% { transform: scale(1.1); }
        100% { transform: scale(1); }
    }
    
    .tag:hover {
        transform: translateY(-3px) scale(1.1);
        box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
    }
    
    .search-tags .tag {
        background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    }
    
    .reference-box {
        background: linear-gradient(135deg, #e0f7fa 0%, #b2ebf2 100%);
        padding: 25px;
        border-radius: 12px;
        margin: 30px 0;
        border-left: 6px solid #00acc1;
    }
    
    .reference-box h4 {
        font-size: 20px;
        font-weight: 700;
        color: #00838f;
        margin-bottom: 15px;
    }
    
    .reference-box ul {
        margin: 0;
        padding-left: 20px;
    }
    
    .reference-box li {
        color: #00695c;
        font-weight: 500;
    }
    
    .reference-box a {
        color: #00838f;
        text-decoration: none;
        font-weight: 600;
        transition: all 0.3s ease;
    }
    
    .reference-box a:hover {
        color: #00acc1;
        text-decoration: underline;
    }
    
    .case-study {
        background: linear-gradient(135deg, #ffeef8 0%, #ffe8f5 100%);
        padding: 25px;
        border-radius: 12px;
        margin: 25px 0;
        border-left: 6px solid #f5576c;
        animation: fadeIn 1s ease;
    }
    
    .case-study h4 {
        font-size: 20px;
        font-weight: 700;
        color: #d81b60;
        margin-bottom: 15px;
    }
    
    .case-study p {
        color: #4a5568;
        margin-bottom: 12px;
    }
    
    .floating-toc {
        background: white;
        padding: 25px;
        border-radius: 12px;
        box-shadow: 0 5px 20px rgba(0,0,0,0.1);
        animation: slideDown 0.6s ease;
        margin-bottom: 40px;
        border: 2px solid #667eea;
    }
    
    @keyframes slideDown {
        from {
            opacity: 0;
            transform: translateY(-20px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }
    
    .floating-toc h3 {
        background: none;
        border: none;
        padding: 0;
        margin: 0 0 15px 0;
        font-size: 20px;
    }
    
    .floating-toc ul {
        margin: 0;
        padding-left: 0;
        list-style: none;
    }
    
    .floating-toc li {
        margin-bottom: 8px;
        padding-left: 0;
        animation: none;
        opacity: 1;
    }
    
    .floating-toc li::before {
        content: none;
    }
    
    .floating-toc a {
        color: #667eea;
        text-decoration: none;
        font-weight: 500;
        transition: all 0.3s ease;
        display: block;
        padding: 8px 12px;
        border-radius: 6px;
        font-size: 15px;
    }
    
    .floating-toc a:hover {
        background: linear-gradient(135deg, #f6f8fb 0%, #e9ecf4 100%);
        transform: translateX(5px);
    }
    
    @media (max-width: 768px) {
        .content-wrapper {
            padding: 30px 20px;
        }
        
        h1 {
            font-size: 32px;
        }
        
        h2 {
            font-size: 26px;
        }
        
        h3 {
            font-size: 20px;
        }
        
        .stat-grid,
        .prevention-grid {
            grid-template-columns: 1fr;
        }
        
        .meta-info {
            flex-direction: column;
            gap: 10px;
        }
    }
  
  .hero-thumbnail {
    width: 100%;
    text-align: center;
    margin-bottom: 40px;
    position: relative;
    animation: fadeIn 1.2s ease;
}

.hero-img-wrapper img {
    width: 60%;
    max-width: 420px;
    border-radius: 20px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.15);
    margin: 0 auto;
}

.hero-caption {
    margin-top: 25px;
}

.hero-title {
    font-size: 38px;
    font-weight: 900;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    margin-bottom: 10px;
    animation: titleGlow 3s ease-in-out infinite;
}

.hero-sub {
    font-size: 18px;
    color: #444;
    font-weight: 500;
    opacity: 0.9;
}

/* Dark mode 대응 */
@media (prefers-color-scheme: dark) {
    .hero-sub {
        color: #ddd !important;
    }
}

/* 애니메이션 */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes titleGlow {
    0%,100% { filter: brightness(1); }
    50% { filter: brightness(1.25); }
}

/* 모바일 최적화 */
@media (max-width: 768px) {
    .hero-img-wrapper img {
        width: 80%;
    }
    .hero-title {
        font-size: 30px;
    }
    .hero-sub {
        font-size: 16px;
    }
}
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;blog-container&quot;&gt;
&lt;div class=&quot;content-wrapper&quot;&gt;
&lt;div class=&quot;read-time&quot;&gt;예상 읽기 시간 : 약 18분&lt;/div&gt;
&lt;div class=&quot;hero-thumbnail&quot;&gt;
&lt;div class=&quot;hero-img-wrapper&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFvTdN/dJMcaiuX1HL/lkLCYKlp0ZwaffR4BVQQy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFvTdN/dJMcaiuX1HL/lkLCYKlp0ZwaffR4BVQQy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFvTdN/dJMcaiuX1HL/lkLCYKlp0ZwaffR4BVQQy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFvTdN%2FdJMcaiuX1HL%2FlkLCYKlp0ZwaffR4BVQQy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hero-caption&quot;&gt;
&lt;h1 class=&quot;hero-title&quot;&gt;랜섬웨어 완벽 가이드&lt;/h1&gt;
&lt;p class=&quot;hero-sub&quot; data-ke-size=&quot;size16&quot;&gt;원리 &amp;middot; 배포 경로 &amp;middot; 예방 &amp;middot; 대응 총정리&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;meta-info&quot;&gt;
&lt;div class=&quot;meta-item&quot;&gt;정보보안&lt;/div&gt;
&lt;div class=&quot;meta-item&quot;&gt;랜섬웨어 대응&lt;/div&gt;
&lt;div class=&quot;meta-item&quot;&gt;2025년 최신 정보&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;floating-toc&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;목차&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#intro&quot;&gt;왜 지금 랜섬웨어를 알아야 하는가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#what&quot;&gt;랜섬웨어란 무엇인가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#principle&quot;&gt;랜섬웨어의 작동 원리&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#distribution&quot;&gt;주요 배포 경로&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#cases&quot;&gt;최근 주요 사례&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prevention&quot;&gt;예방 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#government&quot;&gt;정부 공식 문서 및 대응 체계&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#recovery&quot;&gt;복구 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;마무리&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;section id=&quot;intro&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 랜섬웨어를 알아야 하는가&lt;/h2&gt;
&lt;div class=&quot;intro-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 몇 년간 전 세계적으로 랜섬웨어 공격이 급증하면서, 개인부터 대기업, 정부 기관까지 막대한 피해를 입고 있습니다. 단순히 컴퓨터 바이러스의 일종으로 생각했던 랜섬웨어는 이제 조직의 운영을 마비시키고 수십억 원의 금전적 손실을 야기하는 심각한 사이버 위협으로 자리 잡았습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;stat-grid&quot;&gt;
&lt;div class=&quot;stat-card&quot;&gt;
&lt;div class=&quot;stat-number&quot;&gt;493억원&lt;/div&gt;
&lt;div class=&quot;stat-label&quot;&gt;2024년 평균 피해액&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;stat-card&quot;&gt;
&lt;div class=&quot;stat-number&quot;&gt;11초&lt;/div&gt;
&lt;div class=&quot;stat-label&quot;&gt;랜섬웨어 공격 발생 주기&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;stat-card&quot;&gt;
&lt;div class=&quot;stat-number&quot;&gt;72%&lt;/div&gt;
&lt;div class=&quot;stat-label&quot;&gt;중소기업 타겟 비율&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 랜섬웨어가 무엇인지, 어떻게 작동하는지, 주요 감염 경로는 무엇인지, 그리고 가장 중요한 예방과 대응 방법까지 실무에서 바로 활용할 수 있는 정보를 전문가와 초보자 모두가 이해할 수 있도록 상세하게 정리했습니다. 정부 공식 문서와 최신 보안 동향을 기반으로 작성되었으니, 끝까지 읽어보시고 소중한 데이터를 안전하게 지키시기 바랍니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;what&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜섬웨어란 무엇인가&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 랜섬웨어의 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜섬웨어(Ransomware)는 &lt;span class=&quot;highlight&quot;&gt;랜섬(Ransom, 몸값)&lt;/span&gt;과 &lt;span class=&quot;highlight&quot;&gt;소프트웨어(Software)&lt;/span&gt;의 합성어로, 사용자의 파일이나 시스템을 암호화하여 사용할 수 없게 만든 뒤, 이를 복구하는 대가로 금전을 요구하는 악성 소프트웨어입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말해, 여러분의 중요한 문서, 사진, 데이터베이스 등을 디지털 자물쇠로 잠가버린 후 &quot;열쇠를 원하면 돈을 내라&quot;라고 협박하는 것입니다. 마치 현실 세계에서 인질을 잡고 몸값을 요구하는 것과 동일한 개념이지만, 디지털 환경에서 발생한다는 차이가 있습니다.&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;랜섬웨어의 역사는 1989년 AIDS Trojan까지 거슬러 올라가지만, 본격적으로 위협이 된 것은 2013년 CryptoLocker가 등장하면서부터입니다. 이후 WannaCry(2017), NotPetya(2017), Ryuk(2018), Sodinokibi/REvil(2019), LockBit(2019-현재) 등 점점 더 정교하고 파괴적인 변종들이 등장하고 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;1.2 랜섬웨어의 종류&lt;/h3&gt;
&lt;div class=&quot;table-container&quot;&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;대표 사례&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;암호화형&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;파일을 암호화하여 접근 불가능하게 만듦&lt;/td&gt;
&lt;td&gt;WannaCry, Ryuk, LockBit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;잠금형&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;시스템 자체를 잠가 사용 불가능하게 만듦&lt;/td&gt;
&lt;td&gt;Reveton, WinLocker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;유출협박형&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;데이터를 탈취하여 공개하겠다고 협박&lt;/td&gt;
&lt;td&gt;Maze, DoppelPaymer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;이중 갈취형&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;암호화 + 데이터 유출 협박 병행&lt;/td&gt;
&lt;td&gt;REvil, Conti, LockBit 3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;info-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에는 단순히 파일을 암호화하는 것을 넘어, 중요한 데이터를 먼저 탈취한 후 암호화하고, 몸값을 지불하지 않으면 데이터를 공개하겠다고 협박하는 &lt;b&gt;이중 갈취(Double Extortion)&lt;/b&gt; 방식이 주류를 이루고 있습니다. 이는 피해자가 백업을 보유하고 있더라도 데이터 유출로 인한 평판 손상과 법적 책임 때문에 몸값을 지불할 수밖에 없게 만드는 전략입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;principle&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜섬웨어의 작동 원리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜섬웨어가 어떻게 작동하는지 이해하면 예방과 대응에 큰 도움이 됩니다. 일반적인 랜섬웨어 공격은 다음과 같은 단계로 진행됩니다.&lt;/p&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1단계 : 초기 침투 (Initial Access)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 피싱 이메일, 취약한 원격 접속 서비스(RDP), 악성 웹사이트, 소프트웨어 취약점 등을 통해 시스템에 최초로 침입합니다. 이 단계에서는 사용자가 악성 첨부파일을 열거나 악성 링크를 클릭하는 등의 행위가 발생하는 경우가 많습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2단계 : 권한 상승 및 내부 이동 (Privilege Escalation &amp;amp; Lateral Movement)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 침투에 성공한 공격자는 시스템 내에서 관리자 권한을 획득하려 시도합니다. Windows의 경우 취약한 설정이나 패치되지 않은 보안 허점을 이용해 권한을 상승시킵니다. 이후 네트워크 내 다른 시스템으로 이동하여 공격 범위를 확대합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3단계 : 데이터 탐색 및 탈취 (Data Discovery &amp;amp; Exfiltration)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 네트워크 내에서 중요한 데이터(고객 정보, 재무 데이터, 기밀 문서 등)를 찾아냅니다. 최근 랜섬웨어 그룹들은 암호화 전에 이러한 데이터를 외부 서버로 유출시켜 이중 갈취의 수단으로 활용합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4단계 : 암호화 실행 (Encryption)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계가 랜섬웨어 공격의 핵심입니다. 공격자는 &lt;span class=&quot;highlight&quot;&gt;AES-256, RSA-2048 이상의 강력한 암호화 알고리즘&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;대칭키 암호화 (AES)&lt;/b&gt; : 각 파일은 고유한 AES-256 키로 암호화됩니다. AES는 암호화와 복호화 속도가 빠르기 때문에 대용량 파일 처리에 적합합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비대칭키 암호화 (RSA)&lt;/b&gt; : AES로 파일을 암호화한 후, 그 AES 키 자체를 RSA 공개키로 암호화합니다. RSA 개인키는 공격자만 가지고 있으므로, 공격자 없이는 AES 키를 복구할 수 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타겟 파일 선별&lt;/b&gt; : 모든 파일을 암호화하지 않습니다. 문서(.docx, .xlsx, .pdf), 이미지(.jpg, .png), 데이터베이스(.sql, .mdb), 백업 파일(.bak), 압축 파일(.zip, .rar) 등 가치가 높은 확장자만 선별적으로 암호화합니다. 운영체제 핵심 파일은 암호화하지 않아 시스템이 부팅되고 몸값 요구 메시지를 표시할 수 있게 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;암호화 속도&lt;/b&gt; : 최신 랜섬웨어는 멀티스레딩을 사용하여 여러 파일을 동시에 처리합니다. SSD 기준으로 1GB 파일을 수 초 내에 암호화할 수 있으며, 일반적인 사무용 PC의 모든 문서를 10분 이내에 암호화할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;원본 파일 삭제&lt;/b&gt; : 암호화된 사본을 만든 후 원본 파일은 안전하게 삭제됩니다. 단순 삭제가 아닌 덮어쓰기(Overwrite) 방식을 사용하여 데이터 복구 도구로도 복원할 수 없게 만듭니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;섀도우 카피 삭제&lt;/b&gt; : Windows의 볼륨 섀도우 카피(Volume Shadow Copy)와 시스템 복원 지점을 삭제하여 Windows 내장 복구 기능을 무력화합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;백업 파일 탐색&lt;/b&gt; : 네트워크 드라이브, 클라우드 동기화 폴더, 외장 하드 등을 탐색하여 백업 파일까지 암호화합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 문서, 이미지, 데이터베이스, 백업 파일 등 가치가 높은 파일들을 우선적으로 암호화합니다. 암호화 속도는 매우 빠르며, 수 분 내에 수천 개의 파일이 암호화될 수 있습니다. 암호화된 파일은 원본 이름에 특정 확장자(. locked,. encrypted,. crypt 등)가 추가되어 쉽게 식별할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5단계 : 몸값 요구 (Ransom Demand)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화가 완료되면 바탕화면에 몸값 요구 메시지가 표시됩니다. 일반적으로 비트코인이나 모네로 같은 암호화폐로 일정 금액을 지불하면 복호화 키를 제공하겠다고 약속합니다. 대부분의 경우 72시간 내에 지불하지 않으면 금액이 상승하거나 복호화 키를 영구 삭제하겠다고 협박합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;warning-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜섬웨어에 사용되는 암호화 알고리즘은 현대 암호학 기술을 기반으로 하며, &lt;b&gt;복호화 키 없이는 사실상 복구가 불가능&lt;/b&gt;합니다. AES-256 암호화의 경우, 전 세계 모든 컴퓨터를 동원해도 수십억 년이 걸려야 해독할 수 있을 정도로 강력합니다. 따라서 예방이 최선의 방어책입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;distribution&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜섬웨어 주요 배포 경로&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜섬웨어가 어떻게 유입되는지 알면 감염을 사전에 차단할 수 있습니다. 다음은 실제로 가장 많이 사용되는 배포 경로들입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1 피싱 이메일 (Phishing Email)&lt;/h3&gt;
&lt;div class=&quot;info-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전체 랜섬웨어 감염의 약 45%&lt;/b&gt;가 피싱 이메일을 통해 발생합니다. 공격자는 택배 배송 안내, 세금 고지서, 업무 문서, 청구서, 법원 소환장 등을 가장한 이메일에 악성 첨부파일(주로 .doc, .xls, .pdf, .zip)을 포함시키거나 악성 링크를 삽입합니다.&lt;/p&gt;
&lt;/div&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;&lt;b&gt;매크로 활성화 유도&lt;/b&gt; : Word나 Excel 파일을 열면 &quot;이 문서는 이전 버전에서 작성되었습니다. 내용을 보려면 매크로를 활성화하세요&quot; 또는 &quot;콘텐츠 사용&quot;을 클릭하라는 메시지가 표시됩니다. 사용자가 매크로를 활성화하면 숨겨진 악성 스크립트가 실행되어 랜섬웨어를 다운로드하고 설치합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;악성 링크 클릭&lt;/b&gt; : &quot;배송 조회하기&quot;, &quot;청구서 확인&quot;, &quot;비밀번호 재설정&quot; 등의 버튼이나 링크를 클릭하면 악성 사이트로 연결됩니다. 이 사이트는 정상 사이트처럼 보이지만, 백그라운드에서 자동으로 랜섬웨어를 다운로드하거나 브라우저 취약점을 악용하여 시스템에 침투합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스피어 피싱 (Spear Phishing)&lt;/b&gt; : 특정 조직이나 개인을 타겟으로 한 정교한 피싱 공격입니다. 공격자는 SNS, LinkedIn, 회사 웹사이트 등에서 정보를 수집하여 실제 업무 담당자 이름, 프로젝트명, 내부 용어 등을 사용합니다. 예를 들어 &quot;김대리님, 지난번 요청하신 Q4 실적 보고서를 첨부합니다&quot;와 같이 매우 구체적이고 신뢰할 만한 내용으로 작성됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CEO 사칭 공격 (CEO Fraud)&lt;/b&gt; : 대표이사나 임원을 사칭하여 &quot;긴급 건이니 첨부 파일 확인 후 바로 처리해주세요&quot;와 같은 긴박한 톤으로 직원에게 압박을 가합니다.&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;&lt;b&gt;발신자 주소 확인&lt;/b&gt; : @naver.com이 아닌 @naver-com.tk처럼 유사한 도메인을 사용하거나, 알 수 없는 메일 주소에서 발송됩니다.&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;24시간 이내&quot;, &quot;즉시 확인&quot;, &quot;법적 조치&quot; 등 긴박감을 조성하여 신중한 판단을 방해합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;첨부파일 확장자&lt;/b&gt; : .exe, .scr, .bat, .js, .vbs 등 실행 파일이거나, .zip 안에 실행 파일이 들어있는 경우가 많습니다. document.pdf.exe처럼 이중 확장자를 사용하기도 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;링크 주소 확인&lt;/b&gt; : 링크 위에 마우스를 올려보면(클릭하지 말고) 실제 URL이 표시됩니다. 표시된 텍스트와 실제 URL이 다르면 의심해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2 원격 데스크톱 프로토콜(RDP) 공격&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDP(Remote Desktop Protocol)는 Microsoft가 개발한 프로토콜로, 원격으로 다른 컴퓨터에 접속하여 마치 그 컴퓨터 앞에 앉아 있는 것처럼 사용할 수 있게 해줍니다. 많은 기업들이 재택근무, 원격 관리, IT 지원 등을 위해 RDP를 사용하지만, 보안 설정이 미흡하면 공격자에게 직접적인 침투 경로를 제공하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RDP가 위험한 이유&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;직접적인 시스템 접근&lt;/b&gt; : RDP로 로그인하면 공격자는 정상 사용자와 동일한 권한을 가지므로, 별도의 권한 상승 과정 없이 바로 파일 암호화나 데이터 탈취를 수행할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터넷 노출&lt;/b&gt; : Shodan, Censys 같은 검색 엔진을 통해 인터넷에 노출된 RDP 포트(기본 3389)를 쉽게 찾을 수 있습니다. 2024년 기준으로 전 세계에 약 300만 개 이상의 RDP 서비스가 인터넷에 직접 노출되어 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;약한 인증&lt;/b&gt; : 많은 시스템이 여전히 단순한 비밀번호만으로 보호되고 있으며, 다중 인증(MFA)이 설정되지 않은 경우가 많습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RDP를 통한 공격 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;무차별 대입 공격(Brute Force Attack)&lt;/b&gt; : 공격자는 자동화 도구(Hydra, Medusa 등)를 사용하여 일반적인 비밀번호 조합(admin/admin, administrator/password, user123/password123 등)과 사전 공격(Dictionary Attack)을 수행합니다. 계정 잠금 정책이 없거나 느슨하면 수백만 개의 조합을 시도할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자격증명 스터핑(Credential Stuffing)&lt;/b&gt; : 다크웹에서 유출된 수십억 개의 이메일/비밀번호 조합 데이터베이스를 구매하여 RDP 로그인을 시도합니다. 많은 사람들이 여러 서비스에서 동일한 비밀번호를 사용하므로 성공률이 높습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포트 스캐닝&lt;/b&gt; : Masscan, Nmap 같은 도구로 특정 IP 대역에서 3389 포트가 열려 있는 시스템을 찾아냅니다. 발견된 시스템에 대해 자동으로 로그인 시도를 수행합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BlueKeep 등 RDP 취약점 악용&lt;/b&gt; : 2019년 발견된 BlueKeep(CVE-2019-0708)처럼 RDP 자체의 보안 취약점을 악용하여 인증 없이 시스템에 침투하는 경우도 있습니다.&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;p data-ke-size=&quot;size16&quot;&gt;공격자가 RDP로 로그인에 성공하면, 먼저 시스템을 조사합니다. 네트워크 구조를 파악하고, 백업 위치를 찾으며, 중요 데이터가 어디에 있는지 확인합니다. 그 다음 백신 소프트웨어를 비활성화하고, Windows Defender를 끄고, 방화벽 규칙을 수정합니다. 준비가 완료되면 랜섬웨어를 업로드하여 실행하거나, 네트워크 공유를 통해 다른 시스템으로 전파합니다. 이 모든 과정은 정상적인 관리 작업처럼 보이므로 탐지가 어렵습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.3 악성 웹사이트 및 드라이브 바이 다운로드&lt;/h3&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;멀버타이징(Malvertising)&lt;/b&gt; : 합법적인 광고 네트워크에 악성 광고를 게재하여, 사용자가 광고를 클릭하거나 광고가 표시된 페이지를 방문하기만 해도 감염됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;워터링 홀 공격&lt;/b&gt; : 특정 업계나 조직의 사람들이 자주 방문하는 웹사이트를 해킹하여 악성코드를 심어둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.4 소프트웨어 취약점 악용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제나 애플리케이션의 보안 취약점을 이용해 랜섬웨어를 설치합니다. 대표적인 사례가 2017년 전 세계적으로 큰 피해를 입힌 &lt;b&gt;WannaCry&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;EternalBlue 취약점&lt;/b&gt; : WannaCry는 Windows SMB 프로토콜의 취약점을 악용하여 네트워크 내에서 자동으로 전파되었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제로데이 취약점&lt;/b&gt; : 아직 패치가 나오지 않은 알려지지 않은 취약점을 악용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오래된 시스템&lt;/b&gt; : 보안 업데이트가 중단된 구형 운영체제(Windows 7, Windows Server 2008 등)는 특히 취약합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.5 공급망 공격 (Supply Chain Attack)&lt;/h3&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;Kaseya VSA 공격&lt;/b&gt; : 2021년, REvil 랜섬웨어 그룹이 IT 관리 소프트웨어인 Kaseya VSA를 해킹하여 전 세계 수천 개 기업에 랜섬웨어를 배포했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소프트웨어 업데이트 변조&lt;/b&gt; : 정상적인 소프트웨어 업데이트에 악성코드를 삽입하여 배포합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.6 USB 및 이동식 저장장치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감염된 USB 드라이브나 외장 하드를 컴퓨터에 연결하면 자동으로 랜섬웨어가 실행되는 경우도 있습니다. 특히 폐쇄망 환경에서는 이러한 물리적 매체가 주요 감염 경로가 됩니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;cases&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;최근 주요 랜섬웨어 사례&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 발생한 대규모 랜섬웨어 공격 사례를 통해 그 심각성과 대응 방법을 배울 수 있습니다. 다음은 전 세계적으로 큰 영향을 미친 주요 사건들입니다.&lt;/p&gt;
&lt;div class=&quot;case-study&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;WannaCry 글로벌 대란 (2017년 5월)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 그룹&lt;/b&gt; : 북한 연계 해킹 그룹으로 추정 (Lazarus Group)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피해 규모&lt;/b&gt; : 전 세계 150개국 이상, 약 30만 대의 컴퓨터가 감염되었으며, 총 피해액은 약 40억 달러(약 4조 8천억 원)로 추산됩니다. 영국의 국가보건서비스(NHS)는 81개 병원이 마비되어 수술이 취소되고 응급실이 폐쇄되는 등 심각한 피해를 입었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 방법&lt;/b&gt; : NSA(미국 국가안보국)에서 유출된 EternalBlue 취약점을 악용하여 Windows SMB 프로토콜의 보안 허점을 통해 자동으로 전파되었습니다. 패치되지 않은 Windows 7과 Windows Server 시스템이 주요 타겟이 되었으며, 한 번 감염되면 네트워크 내 모든 취약한 시스템으로 자동 확산되는 웜(Worm) 형태였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영향 및 교훈&lt;/b&gt; : 이 사건은 전 세계적으로 사이버 보안의 중요성을 일깨웠습니다. 특히 오래된 운영체제의 위험성과 정기적인 보안 패치의 필수성이 부각되었으며, 많은 기업과 기관이 백업 시스템과 재해 복구 계획을 재정비하는 계기가 되었습니다. Microsoft는 이미 지원이 종료된 Windows XP에 대해서도 긴급 보안 패치를 제공했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;case-study&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Colonial Pipeline 미국 에너지 인프라 공격 (2021년 5월)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 그룹&lt;/b&gt; : DarkSide (러시아 기반 랜섬웨어 조직)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피해 규모&lt;/b&gt; : 미국 동부 해안 연료 공급의 45%를 담당하는 송유관 시스템이 6일간 완전히 마비되었으며, 하루 250만 배럴의 연료 운송이 중단되었습니다. Colonial Pipeline은 440만 달러(약 49억 원)의 비트코인 몸값을 지불했으며, 미국 정부는 일부 금액을 추적하여 회수했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 방법&lt;/b&gt; : 공격자들은 다크웹에서 유출된 VPN 계정 정보를 구매하여 Colonial Pipeline의 네트워크에 접근했습니다. 해당 VPN 계정은 다중 인증(MFA)이 설정되지 않았으며, 더 이상 사용하지 않는 계정이었지만 비활성화되지 않은 상태였습니다. 공격자들은 약 90GB의 데이터를 탈취한 후 시스템을 암호화했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영향 및 교훈&lt;/b&gt; : 미국 동부 지역 주유소에서 대규모 연료 부족 사태가 발생했으며, 일부 지역에서는 주유소의 70% 이상이 연료가 바닥났습니다. 바이든 대통령은 국가 비상사태를 선포했으며, 이 사건 이후 미국은 랜섬웨어를 국가 안보 위협으로 공식 지정했습니다. 중요 인프라 보호를 위한 새로운 사이버 보안 규제가 도입되었으며, 모든 VPN 계정에 대한 MFA 의무화가 권고되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;case-study&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Kaseya VSA 공급망 공격 (2021년 7월)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 그룹&lt;/b&gt; : REvil (Sodinokibi) - 러시아 기반 조직&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피해 규모&lt;/b&gt; : IT 관리 소프트웨어인 Kaseya VSA를 사용하는 약 60개의 MSP(관리형 서비스 제공업체)와 그들의 고객사 약 1,500개 기업이 동시에 감염되었습니다. 공격자들은 초기에 7,000만 달러(약 800억 원)의 몸값을 요구했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 방법&lt;/b&gt; : 공격자들은 Kaseya VSA의 제로데이 취약점을 발견하고 악용했습니다. 이 소프트웨어는 IT 서비스 제공업체들이 여러 고객사의 시스템을 원격으로 관리하는 데 사용되므로, 하나의 취약점을 통해 수천 개의 기업을 동시에 공격할 수 있었습니다. 공격은 금요일 오후(미국 독립기념일 연휴 직전)에 실행되어 대응 시간을 최소화했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영향 및 교훈&lt;/b&gt; : 스웨덴의 대형 슈퍼마켓 체인 Coop의 800개 매장이 영업을 중단했으며, POS 시스템과 계산대가 모두 작동을 멈췄습니다. 뉴질랜드의 여러 학교와 유치원도 폐쇄되었습니다. 이 사건은 공급망 공격(Supply Chain Attack)의 위험성을 명확히 보여주었으며, 신뢰할 수 있는 소프트웨어 공급업체라도 보안 취약점이 있을 수 있음을 증명했습니다. 많은 기업들이 제3자 소프트웨어에 대한 보안 평가를 강화하게 되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;case-study&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;JBS Foods 글로벌 육류 공급망 공격 (2021년 6월)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 그룹&lt;/b&gt; : REvil&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피해 규모&lt;/b&gt; : 세계 최대 육류 가공업체인 JBS의 미국, 캐나다, 호주 전역의 공장이 일시적으로 가동 중단되었습니다. 미국 쇠고기 생산량의 약 20%가 영향을 받았으며, JBS는 1,100만 달러(약 123억 원)의 몸값을 지불했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 방법&lt;/b&gt; : 공격자들은 JBS의 북미 및 호주 IT 시스템을 타겟으로 하여 생산 관리 시스템과 서버를 암호화했습니다. 백업 시스템은 무사했지만, 완전한 복구에는 시간이 필요했고, 식품 공급망 차질을 우려하여 몸값을 지불하기로 결정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영향 및 교훈&lt;/b&gt; : 미국 농무부는 육류 가격 급등과 공급 부족을 우려했으며, 백악관이 직접 개입하여 상황을 모니터링했습니다. 이 사건은 식품 공급망의 디지털 의존도와 랜섬웨어가 국가 식량 안보에 미칠 수 있는 영향을 보여주었습니다. 제조업 및 물류 산업에서 운영 기술(OT) 시스템의 보안 강화 필요성이 대두되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;case-study&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대만 반도체 업체 TSMC 협력업체 공격 (2023년 6월)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 그룹&lt;/b&gt; : LockBit 3.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피해 규모&lt;/b&gt; : 세계 최대 반도체 제조업체 TSMC의 주요 협력업체인 Kinmax Technology가 공격당해 약 7,000만 달러(약 900억 원)의 몸값을 요구받았습니다. 공격자들은 TSMC와 Apple, AMD 등 주요 고객사의 기밀 정보를 탈취했다고 주장했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 방법&lt;/b&gt; : LockBit 3.0은 이중 갈취(Double Extortion) 전략을 사용하여 먼저 약 1.5TB의 데이터를 탈취한 후 시스템을 암호화했습니다. 탈취된 데이터에는 제품 설계도, 고객 정보, 재무 데이터 등이 포함된 것으로 알려졌으며, 몸값을 지불하지 않으면 이를 공개하겠다고 협박했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영향 및 교훈&lt;/b&gt; : 글로벌 반도체 공급망에 대한 우려가 증가했으며, 특히 중요한 기술 정보가 유출될 가능성에 업계가 긴장했습니다. TSMC는 직접적인 피해는 없었지만 협력업체를 통한 간접적인 데이터 유출 위험을 재평가했습니다. 이 사건 이후 제조업 분야에서 공급망 전체의 사이버 보안 수준을 균일하게 높이는 것의 중요성이 강조되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;case-study&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;한국 주요 기업 및 기관 연쇄 공격 (2023-2024년)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피해 규모&lt;/b&gt; : 2024년 상반기에만 국내에서 랜섬웨어 관련 신고가 전년 대비 34% 증가했으며, 주요 제조업체(자동차 부품, 반도체 장비), 물류업체, 의료기관, 건설사 등이 연쇄적으로 공격당했습니다. 국내 중견 제조업체의 경우 평균 15억~50억 원의 몸값을 요구받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 공격 그룹&lt;/b&gt; : LockBit 3.0, ALPHV/BlackCat, Play 랜섬웨어, Akira 등 다양한 랜섬웨어 조직이 한국 기업을 타겟으로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 방법&lt;/b&gt; : 대부분의 공격은 취약한 VPN 또는 RDP를 통한 초기 침투로 시작되었으며, 일부는 공급망 공격이나 스피어 피싱을 활용했습니다. 이중 갈취 방식이 주를 이루었으며, 개인정보보호법 위반에 따른 과징금과 소송 우려를 악용하여 몸값 지불을 압박했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징 및 영향&lt;/b&gt; : 한국 기업들은 특히 중소기업의 경우 보안 투자가 부족하여 공격자들의 주요 타겟이 되고 있습니다. 공격자들은 한국 기업의 재무 상황을 사전에 조사하여 지불 능력이 있는 기업을 선별적으로 공격합니다. 또한 한국어로 된 협박 메시지를 사용하고, 한국 시간대에 맞춰 공격을 실행하는 등 점점 더 정교해지고 있습니다. KISA에 따르면 공격당한 기업 중 약 30%가 몸값을 지불했지만, 이 중 15%는 완전한 복구에 실패했습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;info-box&quot;&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;표적화된 공격 (Targeted Attack)&lt;/b&gt; : 과거의 무차별적 공격에서 벗어나, 공격 대상 기업을 면밀히 조사한 후 재무 상황, 업종, 중요도를 평가하여 선별적으로 공격합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이중/삼중 갈취&lt;/b&gt; : 단순 암호화를 넘어 데이터 탈취 후 협박, DDoS 공격 병행, 고객/파트너사에 직접 연락하여 압박하는 등 다각도의 압박 전술을 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;공급망 공격 증가&lt;/b&gt; : 보안이 강화된 대기업 대신 상대적으로 취약한 협력업체나 소프트웨어 공급사를 먼저 공격하여 간접적으로 대기업에 침투합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RaaS 모델 확산&lt;/b&gt; : 랜섬웨어 서비스(Ransomware as a Service) 모델로, 기술이 없는 범죄자도 일정 수수료를 내고 랜섬웨어 플랫폼을 이용할 수 있게 되어 공격 건수가 급증했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요 인프라 타겟팅&lt;/b&gt; : 에너지, 의료, 교통, 금융 등 중요 인프라를 공격하여 사회적 혼란을 야기하고 더 높은 몸값을 받아냅니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;prevention&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜섬웨어 예방 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜섬웨어는 일단 감염되면 복구가 매우 어렵기 때문에, &lt;span class=&quot;highlight&quot;&gt;예방이 최선의 방어책&lt;/span&gt;입니다. 다음은 개인과 조직이 반드시 실천해야 할 예방 조치들입니다.&lt;/p&gt;
&lt;div class=&quot;prevention-grid&quot;&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정기적인 백업&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3-2-1 백업 규칙&lt;/b&gt;을 따르세요. 3개의 복사본을 2개의 서로 다른 매체에 저장하고, 1개는 오프라인(외부 위치)에 보관합니다. 백업은 네트워크에서 분리된 외장 하드나 클라우드(버전 관리 지원)에 저장하며, 자동 백업을 설정하되 복구 테스트도 정기적으로 수행해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;운영체제 및 소프트웨어 업데이트&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows Update를 활성화하여 자동 업데이트를 설정하고, 사용하는 모든 소프트웨어(브라우저, PDF 뷰어, Office 등)를 최신 버전으로 유지합니다. 보안 패치는 발표 즉시 적용하는 것이 중요하며, 지원이 종료된 운영체제(Windows 7 등)는 최신 버전으로 교체해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;강력한 보안 솔루션 사용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신뢰할 수 있는 백신 소프트웨어를 설치하고 실시간 보호 기능을 활성화합니다. EDR(Endpoint Detection and Response) 솔루션을 도입하면 더욱 효과적입니다. 방화벽을 활성화하고, 안티 랜섬웨어 전용 솔루션도 고려할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이메일 및 링크 주의&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발신자가 불명확하거나 예상하지 못한 이메일의 첨부파일은 절대 열지 않습니다. 링크를 클릭하기 전에 URL을 확인하고, 의심스러운 경우 발신자에게 별도로 연락하여 확인합니다. 이메일 보안 게이트웨이를 구축하면 피싱 메일을 자동으로 차단할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;매크로 비활성화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft Office 문서의 매크로는 기본적으로 비활성화하고, 반드시 필요한 경우에만 신뢰할 수 있는 출처의 파일에서만 활성화합니다. Office 보안 센터에서 &quot;모든 매크로 포함 안 함&quot; 설정을 권장합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;RDP 보안 강화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDP를 사용하지 않는다면 완전히 비활성화합니다. 사용이 필요한 경우 복잡한 비밀번호를 설정하고, 다중 인증(MFA)을 반드시 적용합니다. VPN을 통해서만 RDP 접근을 허용하고, 기본 포트(3389)를 변경하며, 로그인 실패 횟수를 제한합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;권한 최소화 원칙&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일상 업무에는 일반 사용자 계정을 사용하고, 관리자 권한은 필요한 경우에만 사용합니다. 각 사용자에게 업무에 필요한 최소한의 권한만 부여하고, 공유 폴더의 쓰기 권한을 제한합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;네트워크 세분화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크를 여러 세그먼트로 분리하여 랜섬웨어가 전체 네트워크로 확산되는 것을 방지합니다. 중요한 서버와 일반 사용자 네트워크를 분리하고, 방화벽 규칙을 통해 불필요한 통신을 차단합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;직원 교육 및 인식 제고&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 직원에게 정기적으로 보안 교육을 실시합니다. 피싱 메일 식별법, 안전한 인터넷 사용법, 의심스러운 활동 신고 절차 등을 교육합니다. 모의 피싱 훈련을 통해 실제 상황에 대비합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파일 확장자 표시 활성화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows 탐색기에서 파일 확장자를 표시하도록 설정하여, document.pdf.exe처럼 확장자를 위장한 악성 파일을 쉽게 식별할 수 있습니다. 이중 확장자를 가진 파일은 매우 의심스럽습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클라우드 서비스 버전 관리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OneDrive, Google Drive 등 클라우드 서비스를 사용하는 경우, 파일 버전 관리 기능을 활성화합니다. 랜섬웨어에 감염되더라도 이전 버전으로 복원할 수 있습니다. 대부분의 클라우드 서비스는 30일 이상의 버전 이력을 제공합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;prevention-card&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;침입 탐지 시스템(IDS/IPS)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 트래픽을 모니터링하여 비정상적인 활동을 탐지하고 차단하는 침입 탐지/방지 시스템을 구축합니다. 랜섬웨어의 C&amp;amp;C(Command and Control) 서버 통신을 차단할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;warning-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;백업만으로는 충분하지 않습니다!&lt;/b&gt; 최근 랜섬웨어는 백업 파일도 함께 암호화하거나 삭제합니다. 따라서 백업은 반드시 네트워크에서 분리된 상태로 보관해야 하며, immutable(변경 불가능) 백업 기능을 지원하는 솔루션을 사용하는 것이 좋습니다. 또한 데이터 유출을 막기 위한 DLP(Data Loss Prevention) 솔루션도 함께 고려해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;government&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정부 공식 문서 및 대응 체계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국 정부는 랜섬웨어 위협에 대응하기 위해 다양한 공식 문서와 지원 체계를 운영하고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.1 과학기술정보통신부 및 KISA(한국인터넷진흥원)&lt;/h3&gt;
&lt;div class=&quot;reference-box&quot;&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;&lt;b&gt;랜섬웨어 대응 가이드&lt;/b&gt; : KISA에서 발간하는 공식 대응 가이드로, 예방부터 대응, 복구까지의 전 과정을 설명합니다. (&lt;a href=&quot;https://www.kisa.or.kr/2060204/form?postSeq=12&amp;amp;lang_type=KO&amp;amp;page=1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.kisa.or.kr&lt;/a&gt;에서 다운로드 가능)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안공지 및 주의보&lt;/b&gt; : 새로운 랜섬웨어 변종이 발견되거나 대규모 공격이 예상될 때 발행되는 보안 경보입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;침해사고 대응 지원&lt;/b&gt; : 랜섬웨어 감염 시 무료 상담 및 기술 지원을 제공합니다. (국번 없이 118)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안취약점 정보&lt;/b&gt; : 운영체제 및 주요 소프트웨어의 보안 취약점 정보와 패치 안내를 제공합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중소기업 정보보호 컨설팅&lt;/b&gt; : 중소기업을 대상으로 무료 보안 컨설팅 및 취약점 점검 서비스를 제공합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.2 국가사이버안전센터 (NCSC)&lt;/h3&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;국가 사이버 위협 경보&lt;/b&gt; : 국가 안보에 영향을 미칠 수 있는 대규모 랜섬웨어 공격 시 경보 발령&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주요기반시설 보호&lt;/b&gt; : 전력, 통신, 금융 등 국가 주요기반시설에 대한 사이버 보안 강화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;국제 협력&lt;/b&gt; : Interpol, FBI 등 해외 기관과의 공조를 통한 글로벌 랜섬웨어 조직 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.3 금융보안원 (FSS)&lt;/h3&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;금융권 랜섬웨어 대응 매뉴얼&lt;/b&gt; : 금융기관 특성에 맞춘 상세한 대응 절차&lt;/li&gt;
&lt;li&gt;&lt;b&gt;금융 ISAC&lt;/b&gt; : 금융권 보안 위협 정보 공유 및 협력 체계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모의훈련 지원&lt;/b&gt; : 랜섬웨어 공격 대응 모의훈련 시나리오 및 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.4 경찰청 사이버안전국&lt;/h3&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;사이버범죄 신고&lt;/b&gt; : 경찰청 사이버안전국 (&lt;a href=&quot;https://ecrm.police.go.kr/minwon/main&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ecrm.police.go.kr&lt;/a&gt;) 또는 국번 없이 112로 신고 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사이버수사대&lt;/b&gt; : 전국 시도경찰청에 사이버수사대가 설치되어 있으며, 랜섬웨어 범죄 수사 및 피해자 지원을 담당합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불법 거래 추적&lt;/b&gt; : 암호화폐를 통한 몸값 거래 추적 및 범인 검거&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.5 중소벤처기업부 - 중소기업 지원&lt;/h3&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;사이버보안 컨설팅 지원&lt;/b&gt; : 중소기업 대상 무료 또는 저렴한 비용으로 보안 컨설팅 제공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 솔루션 지원&lt;/b&gt; : 백신, 방화벽 등 보안 솔루션 구매 비용 일부 지원&lt;/li&gt;
&lt;li&gt;&lt;b&gt;교육 프로그램&lt;/b&gt; : 중소기업 임직원 대상 사이버 보안 교육&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.6 주요 정부 문서 및 법령&lt;/h3&gt;
&lt;div class=&quot;reference-box&quot;&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;&lt;b&gt;정보통신망 이용촉진 및 정보보호 등에 관한 법률&lt;/b&gt; : 정보통신망의 안전성 확보를 위한 기본 법률&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개인정보 보호법&lt;/b&gt; : 개인정보 침해 시 신고 의무 및 보호 조치 규정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;국가사이버안전관리규정&lt;/b&gt; : 국가 차원의 사이버 안전 관리 체계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사이버보안 진단의 날 운영 지침&lt;/b&gt; : 매월 4째 수요일을 사이버보안 진단의 날로 지정하여 점검 실시&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;info-box&quot;&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;KISA 침해사고 신고 : 국번 없이 &lt;b&gt;118&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;경찰청 사이버범죄 신고 : 국번 없이 &lt;b&gt;112&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;KISA 홈페이지 : &lt;a href=&quot;https://www.kisa.or.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.kisa.or.kr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;보호나라 : &lt;a href=&quot;https://www.boho.or.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.boho.or.kr&lt;/a&gt; (보안 관련 종합 정보)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;recovery&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜섬웨어 복구 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안타깝게도, 말씀하신 대로 &lt;span class=&quot;highlight&quot;&gt;랜섬웨어 감염 후 완벽한 복구는 매우 어렵습니다&lt;/span&gt;. 현대 랜섬웨어가 사용하는 암호화 알고리즘(AES-256, RSA-2048 등)은 복호화 키 없이는 사실상 해독이 불가능합니다. 그러나 상황에 따라 시도해 볼 수 있는 방법들이 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7.1 즉각적인 조치&lt;/h3&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 즉시 네트워크에서 격리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감염된 컴퓨터를 즉시 네트워크에서 분리합니다. 유선 LAN 케이블을 뽑고, Wi-Fi를 끕니다. 이는 랜섬웨어가 네트워크의 다른 시스템으로 확산되는 것을 막기 위함입니다. USB나 외장 하드 등 연결된 모든 저장장치도 분리합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 컴퓨터 종료 여부 판단&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 랜섬웨어는 메모리에 복호화 키의 일부를 남겨둘 수 있습니다. 컴퓨터를 종료하면 이 정보가 사라질 수 있으므로, 전문가의 지시가 있을 때까지 전원을 유지합니다. 다만, 암호화가 진행 중이라면 즉시 종료하는 것이 피해를 줄일 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 증거 보존&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몸값 요구 메시지, 암호화된 파일의 확장자, 범인이 남긴 연락처 등을 사진으로 촬영하거나 별도로 기록합니다. 이는 경찰 수사와 복구에 도움이 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;process-step&quot;&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 전문가에게 연락&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KISA(118), 경찰청, 또는 전문 보안업체에 즉시 연락하여 지원을 요청합니다. 혼자서 복구를 시도하다가 상황을 악화시킬 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7.2 복구 시도 방법&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;방법 1 : 무료 복호화 도구 사용&lt;/h4&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;No More Ransom Project&lt;/b&gt; : Europol, 네덜란드 경찰, Kaspersky, McAfee 등이 운영하는 프로젝트로, 다양한 랜섬웨어의 무료 복호화 도구를 제공합니다. (&lt;a href=&quot;https://www.nomoreransom.org&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.nomoreransom.org&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Avast Free Ransomware Decryption Tools&lt;/b&gt; : Avast에서 제공하는 여러 랜섬웨어 복호화 도구&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Kaspersky Ransomware Decryptor&lt;/b&gt; : Kaspersky에서 제공하는 복호화 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;info-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복호화 도구를 사용하기 전에 반드시 랜섬웨어의 정확한 이름과 버전을 확인해야 합니다. 잘못된 도구를 사용하면 데이터가 영구적으로 손상될 수 있습니다. No More Ransom 웹사이트에는 암호화된 파일을 업로드하면 랜섬웨어 종류를 식별해 주는 기능이 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;방법 2 : 백업에서 복원&lt;/h4&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;백업 무결성 확인&lt;/b&gt; : 복원하기 전에 백업 파일이 암호화되지 않았는지 확인합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;완전 포맷 후 복원&lt;/b&gt; : 감염된 시스템을 완전히 포맷하고 운영체제를 재설치한 후 백업을 복원합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클라우드 버전 복구&lt;/b&gt; : OneDrive, Google Drive 등을 사용했다면 이전 버전으로 복원할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;방법 3 : 섀도우 카피 복원&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows의 시스템 복원 기능이 활성화되어 있었다면, 섀도우 카피(Volume Shadow Copy)를 통해 일부 파일을 복구할 수 있습니다.&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;ShadowExplorer&lt;/b&gt; : 섀도우 카피를 탐색하고 복원할 수 있는 무료 도구&lt;/li&gt;
&lt;li&gt;&lt;b&gt;한계&lt;/b&gt; : 많은 최신 랜섬웨어는 섀도우 카피도 삭제하므로, 성공 가능성은 낮습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;방법 4 : 데이터 복구 소프트웨어 사용&lt;/h4&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;Recuva, PhotoRec, TestDisk&lt;/b&gt; 등의 복구 도구&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주의사항&lt;/b&gt; : 복구 작업은 별도의 드라이브에 저장해야 하며, 원본 드라이브에 추가 작업을 하면 복구 가능성이 낮아집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7.3 몸값 지불에 대한 고려사항&lt;/h3&gt;
&lt;div class=&quot;warning-box&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;몸값 지불은 권장되지 않습니다.&lt;/b&gt; 미국 FBI, 한국 경찰청, 대부분의 보안 전문가들은 다음과 같은 이유로 몸값 지불을 권장하지 않습니다.&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; : 돈을 지불해도 복호화 키를 받지 못하거나, 받더라도 제대로 작동하지 않는 경우가 약 40%에 달합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;재공격 위험&lt;/b&gt; : 돈을 지불한 피해자는 다시 공격받을 확률이 높습니다. 공격자 입장에서는 &quot;돈을 지불할 사람&quot;으로 표시되기 때문입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;범죄 조직 자금 지원&lt;/b&gt; : 몸값은 범죄 조직의 자금원이 되어 더 많은 공격을 야기합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;법적 문제&lt;/b&gt; : 일부 국가에서는 테러 조직으로 지정된 랜섬웨어 그룹에 돈을 지불하는 것 자체가 불법일 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 기업의 경우 사업 연속성, 고객 데이터 보호, 법적 책임 등을 고려하여 불가피하게 몸값 지불을 선택하는 경우도 있습니다. 이런 경우에도 반드시 전문 협상가와 법률 자문을 받아야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7.4 감염 후 조치&lt;/h3&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;전체 시스템 재구축&lt;/b&gt; : 운영체제를 완전히 재설치하고, 모든 소프트웨어를 재설치합니다. 랜섬웨어가 백도어를 설치했을 가능성이 있기 때문입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비밀번호 변경&lt;/b&gt; : 모든 계정의 비밀번호를 변경합니다. 특히 이메일, 은행, 주요 서비스 계정은 우선적으로 변경합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 강화&lt;/b&gt; : 앞서 설명한 예방 조치들을 모두 적용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사고 보고&lt;/b&gt; : 조직 내부 보안팀, 경영진에 보고하고, 필요시 고객이나 이해관계자에게 통지합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사후 분석&lt;/b&gt; : 어떻게 감염되었는지 철저히 분석하여 재발을 방지합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;conclusion&quot;&gt;
&lt;div class=&quot;conclusion-box&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜섬웨어는 현대 사이버 보안에서 가장 심각한 위협 중 하나입니다. 개인의 소중한 추억부터 기업의 핵심 자산까지 순식간에 인질로 만들 수 있는 무서운 공격입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 글에서 설명한 예방 조치들을 철저히 실천한다면, 랜섬웨어로부터 안전하게 시스템과 데이터를 보호할 수 있습니다. 특히 &lt;b&gt;정기적인 백업, 소프트웨어 업데이트, 보안 의식 제고&lt;/b&gt;는 반드시 실천해야 할 핵심 요소입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 불행히도 랜섬웨어에 감염되었다면, 당황하지 말고 즉시 전문가의 도움을 받으시기 바랍니다. 혼자서 해결하려다 상황을 악화시킬 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기억하세요. &lt;b&gt;예방이 최선의 방어&lt;/b&gt;이며, &lt;b&gt;백업이 최후의 보루&lt;/b&gt;입니다. 오늘부터 바로 실천하여 여러분의 소중한 데이터를 지키시기 바랍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;info-box&quot;&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;KISA 침해사고 신고 : 국번 없이 118&lt;/li&gt;
&lt;li&gt;경찰청 사이버범죄 신고 : 국번 없이 112&lt;/li&gt;
&lt;li&gt;KISA 홈페이지 : &lt;a href=&quot;https://www.kisa.or.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.kisa.or.kr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;div class=&quot;tag-container&quot;&gt;
&lt;div class=&quot;tag-title&quot;&gt;&amp;nbsp;태그&lt;/div&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span class=&quot;tag&quot;&gt;랜섬웨어&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;사이버보안&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;정보보안&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;악성코드&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;데이터보호&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;백업&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;피싱&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;보안가이드&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;KISA&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;사이버범죄&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>IT</category>
      <category>기업보안</category>
      <category>데이터 암호화</category>
      <category>랜섬웨어 대응</category>
      <category>랜섬웨어 복구</category>
      <category>랜섬웨어 신고</category>
      <category>랜섬웨어 예방</category>
      <category>랜섬웨어 원리</category>
      <category>보안솔루션</category>
      <category>사이버공격 예방</category>
      <category>중소기업 랜섬웨어</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/561</guid>
      <comments>https://odinbox.tistory.com/561#entry561comment</comments>
      <pubDate>Sat, 29 Nov 2025 09:44:01 +0900</pubDate>
    </item>
    <item>
      <title>CSS 애니메이션 가이드, CSS로 애니메이션을?</title>
      <link>https://odinbox.tistory.com/560</link>
      <description>&lt;div&gt;
&lt;style&gt;
.csspoststyle_post-wrap {
  max-width: 900px;
  margin: 0 auto;
  padding: 32px 20px 60px;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Noto Sans KR&quot;, &quot;Malgun Gothic&quot;, sans-serif;
  color: #222;
  line-height: 1.7;
  box-sizing: border-box;
}
.csspoststyle_post-wrap * {
  box-sizing: border-box;
}
.csspoststyle_title {
  font-size: 2.1rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  margin-bottom: 0.8rem;
}
.csspoststyle_title-highlight {
  position: relative;
  display: inline-block;
}
.csspoststyle_title-highlight::after {
  content: &quot;&quot;;
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 10px;
  background: linear-gradient(90deg, #5c6fff, #4ad395);
  opacity: 0.16;
  transform-origin: left center;
  transform: scaleX(0);
  animation: csspoststyle_title-underline 0.8s 0.4s ease-out forwards;
}
@keyframes csspoststyle_title-underline {
  to {
    transform: scaleX(1);
  }
}
.csspoststyle_subtitle {
  font-size: 0.98rem;
  color: #475569;
  margin-bottom: 22px;
}
.csspoststyle_thumbnail {
  position: relative;
  width: 100%;
  padding-top: 46%;
  border-radius: 18px;
  background: radial-gradient(circle at 10% 20%, #f0f4ff 0, #f7fbff 40%, #f8fff7 100%);
  overflow: hidden;
  margin-bottom: 28px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.08);
}
.csspoststyle_thumbnail-inner {
  position: absolute;
  inset: 16px;
  border-radius: 14px;
  border: 1px dashed rgba(15, 23, 42, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 10px;
  font-size: 0.86rem;
  color: #555;
  text-align: center;
}
.csspoststyle_thumbnail-hint {
  font-size: 0.78rem;
  color: #94a3b8;
}
.csspoststyle_toc {
  margin: 32px 0 36px;
  padding: 18px 18px 16px;
  border-radius: 16px;
  background: linear-gradient(135deg, #f5f7ff, #f7fffb);
  border: 1px solid rgba(148, 163, 184, 0.4);
}
.csspoststyle_toc-title {
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 8px;
}
.csspoststyle_toc-desc {
  font-size: 0.86rem;
  color: #64748b;
  margin-bottom: 10px;
}
.csspoststyle_toc-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
  display: grid;
  gap: 4px;
}
.csspoststyle_toc-list a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.88rem;
  text-decoration: none;
  color: #111827;
  padding: 4px 0;
}
.csspoststyle_toc-list a::before {
  content: &quot;&quot;;
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: linear-gradient(135deg, #6366f1, #22c55e);
}
.csspoststyle_post-wrap h2 {
  font-size: 1.4rem;
  margin: 36px 0 14px;
  font-weight: 800;
  letter-spacing: -0.03em;
}
.csspoststyle_post-wrap h3 {
  font-size: 1.1rem;
  margin: 28px 0 12px;
  font-weight: 700;
}
.csspoststyle_post-wrap p {
  margin: 0 0 12px;
  font-size: 0.96rem;
}
.csspoststyle_post-wrap ul {
  margin: 6px 0 16px 18px;
  padding-left: 6px;
  font-size: 0.95rem;
}
.csspoststyle_inline-key {
  display: inline-flex;
  align-items: center;
  padding: 0 7px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.6);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.csspoststyle_tip {
  margin: 16px 0 20px;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgba(96, 165, 250, 0.4);
  background: linear-gradient(135deg, #f3f7ff, #f5faff);
  font-size: 0.9rem;
  color: #1e293b;
}
.csspoststyle_tip-title {
  font-weight: 700;
  font-size: 0.9rem;
  margin-bottom: 4px;
}
.csspoststyle_section {
  margin: 24px 0 32px;
  padding: 18px 18px 20px;
  border-radius: 16px;
  background: #ffffff;
  border: 1px solid rgba(148, 163, 184, 0.35);
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
  animation: csspoststyle_section-fade 0.7s ease-out both;
}
.csspoststyle_section:nth-of-type(odd) {
  animation-delay: 0.06s;
}
.csspoststyle_section:nth-of-type(even) {
  animation-delay: 0.12s;
}
@keyframes csspoststyle_section-fade {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.csspoststyle_code-block {
  margin: 14px 0 18px;
  border-radius: 14px;
  overflow: hidden;
  background: #020617;
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.7);
}
.csspoststyle_code-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 12px 8px;
  background: #020617;
  border-bottom: 1px solid rgba(148, 163, 184, 0.35);
}
.csspoststyle_code-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #e5e7eb;
}
.csspoststyle_code-dots {
  display: flex;
  gap: 4px;
}
.csspoststyle_code-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
}
.csspoststyle_code-dot:nth-child(1) {
  background: #f97373;
}
.csspoststyle_code-dot:nth-child(2) {
  background: #facc15;
}
.csspoststyle_code-dot:nth-child(3) {
  background: #22c55e;
}
.csspoststyle_code-copy {
  appearance: none;
  border: none;
  border-radius: 999px;
  padding: 4px 11px;
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  background: rgba(15, 23, 42, 0.72);
  color: #e5e7eb;
  backdrop-filter: blur(8px);
  transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.csspoststyle_code-copy:hover {
  background: linear-gradient(135deg, #4f46e5, #16a34a);
  box-shadow: 0 0 0 1px rgba(191, 219, 254, 0.6);
  transform: translateY(-1px);
}
.csspoststyle_code-copy:active {
  transform: translateY(0);
  box-shadow: none;
}
.csspoststyle_code-block pre {
  margin: 0;
  padding: 12px 14px 14px;
  overflow-x: auto;
}
.csspoststyle_code-block code {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, &quot;Liberation Mono&quot;, &quot;Courier New&quot;, monospace;
  font-size: 0.82rem;
  color: #e5e7eb;
  white-space: pre;
}
.csspoststyle_inline-code {
  display: inline-block;
  padding: 0 6px;
  border-radius: 6px;
  background: rgba(148, 163, 184, 0.16);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, &quot;Liberation Mono&quot;, &quot;Courier New&quot;, monospace;
  font-size: 0.85em;
}
.csspoststyle_toast {
  position: fixed;
  left: 50%;
  bottom: 30px;
  transform: translateX(-50%) translateY(16px);
  padding: 9px 16px;
  border-radius: 999px;
  background: #111827;
  color: #f9fafb;
  font-size: 0.82rem;
  box-shadow: 0 18px 35px rgba(15, 23, 42, 0.6);
  opacity: 0;
  pointer-events: none;
  z-index: 9999;
  animation: csspoststyle_toast-in 0.26s ease-out forwards, csspoststyle_toast-out 0.28s ease-in forwards 2.1s;
}
@keyframes csspoststyle_toast-in {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}
@keyframes csspoststyle_toast-out {
  to {
    opacity: 0;
    transform: translateX(-50%) translateY(6px);
  }
}
@media (max-width: 720px) {
  .csspoststyle_post-wrap {
    padding: 24px 14px 48px;
  }
  .csspoststyle_title {
    font-size: 1.7rem;
  }
  .csspoststyle_thumbnail-inner {
    font-size: 0.84rem;
  }
}
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;csspoststyle_post-wrap&quot;&gt;
&lt;h1 class=&quot;csspoststyle_title&quot;&gt;&lt;span class=&quot;csspoststyle_title-highlight&quot;&gt;CSS 애니메이션, 어려우시죠?&lt;/span&gt;&lt;/h1&gt;
&lt;p class=&quot;csspoststyle_subtitle&quot; data-ke-size=&quot;size16&quot;&gt;제가 많이 사용하는 애니메이션과 맨 아래에 참고 CSS 등도 정리를 해서 해봤습니다..&lt;/p&gt;
&lt;div class=&quot;csspoststyle_thumbnail&quot;&gt;
&lt;div class=&quot;csspoststyle_thumbnail-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn27dA/dJMcaiVZopR/HxIdkQixqCabPcR3p8IcI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn27dA/dJMcaiVZopR/HxIdkQixqCabPcR3p8IcI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn27dA/dJMcaiVZopR/HxIdkQixqCabPcR3p8IcI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn27dA%2FdJMcaiVZopR%2FHxIdkQixqCabPcR3p8IcI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;csspoststyle_thumbnail-hint&quot;&gt;CSS를 이 글 하나로 끝낼 수 있어요!&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 웹 디자인에서 애니메이션은 선택이 아니라 기본에 가깝습니다. 적절한 움직임은 사용자의 시선을 끌고, CTA 버튼의 클릭률을 높이며, 브랜드의 인상을 오래 남게 합니다. 특히 개발자와 디자이너에게 CSS 애니메이션은 복잡한 자바스크립트 없이도 인터페이스를 풍부하게 만드는 핵심 도구입니다.&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;아래에서는 실전에서 많이 사용하는 CSS 애니메이션 예제 10가지를 목적별로 정리했습니다. 각 예제는 &lt;span class=&quot;csspoststyle_inline-key&quot;&gt;설명&lt;/span&gt; &amp;rarr; &lt;span class=&quot;csspoststyle_inline-key&quot;&gt;코드&lt;/span&gt; &amp;rarr; &lt;span class=&quot;csspoststyle_inline-key&quot;&gt;실무 팁&lt;/span&gt; 순서로 구성되어 있어 웹 사이트에 바로 가져다 쓸 수 있습니다.&lt;/p&gt;
&lt;div id=&quot;csspoststyle_toc&quot; class=&quot;csspoststyle_toc&quot;&gt;
&lt;div class=&quot;csspoststyle_toc-title&quot;&gt;목차&lt;/div&gt;
&lt;p class=&quot;csspoststyle_toc-desc&quot; data-ke-size=&quot;size16&quot;&gt;각 항목을 클릭하면 해당 애니메이션 예제로 바로 이동합니다.&lt;/p&gt;
&lt;ul class=&quot;csspoststyle_toc-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example1&quot;&gt;1. 자연스러운 페이드인(Fade-in) 효과&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example2&quot;&gt;2. 슬라이드 업&amp;middot;다운 등장 효과&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example3&quot;&gt;3.버튼&amp;middot;이미지 호버 강조 효과&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example4&quot;&gt;4. 3D 카드 플립(Card Flip)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example5&quot;&gt;5. 순수 CSS 로딩 스피너&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example6&quot;&gt;6. 연속 회전 아이콘 효과&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example7&quot;&gt;7. 맥박(Pulse) 강조 애니메이션&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example8&quot;&gt;8. 스켈레톤 로딩(Skeleton UI)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example9&quot;&gt;9. 흔들림(Shake) 오류 피드백&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_example10&quot;&gt;10. 배경&amp;middot;텍스트 컬러 애니메이션&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_consider&quot;&gt;성능&amp;middot;접근성&amp;middot;실무 적용 팁&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#csspoststyle_deeplink&quot;&gt;더 공부할 수 있는 공식 문서 모음&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;CSS 애니메이션 기본 이해, 트랜지션과 키프레임&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;트랜지션(transition)&lt;/b&gt;: &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;:hover&lt;/span&gt;, &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;:focus&lt;/span&gt;, 클래스 토글처럼 상태가 변할 때 시작과 끝 사이를 부드럽게 이어 줍니다. 색상 변화, 크기 조정, 그림자 강조 등 단순한 인터랙션에 적합합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;키프레임 애니메이션(animation)&lt;/b&gt;: &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;@keyframes&lt;/span&gt;로 여러 단계의 스타일을 정의하고 반복 재생합니다. 로딩 스피너, 무한 회전, 배경 색상 순환처럼 계속 움직이는 모션에 적합합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 &lt;b&gt;상태 한 번 전환 + 짧은 모션은 트랜지션&lt;/b&gt;, &lt;b&gt;지속적&amp;middot;복합적인 움직임은 키프레임&lt;/b&gt;으로 나눠 설계하면 유지보수가 훨씬 편해집니다.&lt;/p&gt;
&lt;div id=&quot;csspoststyle_example1&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 자연스러운 페이드인(Fade-in) 효과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 첫 화면에서 타이틀, 대표 이미지를 서서히 등장시키는 가장 기본적인 패턴입니다. 콘텐츠 중심 웹 사이트의 경우, 글 상단 영역에 페이드인을 적용하면 첫인상이 훨씬 부드럽게 느껴집니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_fade-in {
  opacity: 0;
  animation: csspoststyle_fade-in-keyframes 1.5s ease-in forwards;
}

@keyframes csspoststyle_fade-in-keyframes {
  to {
    opacity: 1;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;csspoststyle_inline-code&quot;&gt;forwards&lt;/span&gt; 옵션 덕분에 애니메이션이 끝난 뒤에도 마지막 상태인 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;opacity: 1&lt;/span&gt;이 유지됩니다. 여러 요소를 순차적으로 등장시키고 싶다면 각각에 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;animation-delay&lt;/span&gt;를 0.1초씩 다르게 주면 자연스러운 스태거 효과를 만들 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_tip&quot;&gt;
&lt;div class=&quot;csspoststyle_tip-title&quot;&gt;실무 팁&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크롤과 함께 등장시키고 싶다면 자바스크립트 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;IntersectionObserver&lt;/span&gt;로 특정 섹션이 뷰포트에 들어올 때 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;csspoststyle_fade-in&lt;/span&gt; 클래스를 추가하는 방식으로 확장할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example2&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 부드러운 슬라이드 업&amp;middot;다운 효과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요소가 아래에서 위로 떠오르면서 나타나는 슬라이드 업 효과는 카드형 목록, 알림 바, 모바일 메뉴 등에서 자주 쓰입니다. 단순히 보여 주는 것보다 움직임이 포함되어 더 눈에 잘 들어옵니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_slide-up {
  transform: translateY(50px);
  opacity: 0;
  animation: csspoststyle_slide-up-keyframes 0.8s ease-out forwards;
}

@keyframes csspoststyle_slide-up-keyframes {
  to {
    transform: translateY(0);
    opacity: 1;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위치 이동은 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;top&lt;/span&gt;이나 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;margin&lt;/span&gt; 대신 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;transform&lt;/span&gt;으로 처리했습니다. 브라우저가 GPU 합성 단계에서 처리하기 때문에 레이아웃 재계산이 줄어들어 성능이 더 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 요소를 숨길 때는 시작값과 끝값을 바꿔서 슬라이드 다운 애니메이션을 만들 수 있습니다. 모달, 알림 영역에 등장&amp;middot;퇴장 애니메이션을 모두 붙이고 싶을 때 유용합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example3&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 호버 시 강조 효과 (버튼&amp;middot;이미지 인터랙션)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스를 올렸을 때 살짝 떠오르며 강조되는 효과는 CTA 버튼, 카드, 썸네일 이미지에 거의 필수로 들어가는 패턴입니다. 작은 변화만으로도 &amp;ldquo;클릭 가능한 요소&amp;rdquo;라는 신호를 확실하게 줄 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 18px;
  border-radius: 999px;
  border: none;
  background: linear-gradient(135deg, #4f46e5, #16a34a);
  color: #ffffff;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
}

.csspoststyle_btn:hover {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.3);
  filter: brightness(1.02);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글에서 &amp;ldquo;예제 코드 보기&amp;rdquo;, &amp;ldquo;GitHub 바로가기&amp;rdquo; 같은 버튼에 적용해 보면, 사용자가 어떤 요소를 눌러야 할지 직관적으로 이해할 수 있습니다. 카드 레이아웃에서는 카드 전체를 버튼처럼 처리해 동일한 효과를 주면 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example4&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 3D 카드 플립(Card Flip) 애니메이션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카드 앞면에는 제목과 한 줄 설명, 뒷면에는 세부 설명과 링크를 배치하는 패턴입니다. 포트폴리오, 강의 목록,&amp;nbsp; 진행하는 프로젝트 리스트 등에 활용하기 좋습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;HTML + CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;csspoststyle_card&quot;&amp;gt;
  &amp;lt;div class=&quot;csspoststyle_card-inner&quot;&amp;gt;
    &amp;lt;div class=&quot;csspoststyle_card-front&quot;&amp;gt;
      OdinBOX 애니메이션 가이드
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;csspoststyle_card-back&quot;&amp;gt;
      - CSS 애니메이션 핵심 정리&amp;lt;br /&amp;gt;
      - 실전 예제 10가지&amp;lt;br /&amp;gt;
      - GitHub 샘플 프로젝트 링크
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

.csspoststyle_card {
  perspective: 1000px;
}

.csspoststyle_card-inner {
  position: relative;
  width: 100%;
  max-width: 260px;
  height: 160px;
  margin: 0 auto;
  transition: transform 0.8s;
  transform-style: preserve-3d;
  cursor: pointer;
}

.csspoststyle_card-front,
.csspoststyle_card-back {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 16px;
  padding: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.csspoststyle_card-front {
  background: linear-gradient(135deg, #eef2ff, #e0fbea);
}

.csspoststyle_card-back {
  background: #020617;
  color: #e5e7eb;
  transform: rotateY(180deg);
}

.csspoststyle_card:hover .csspoststyle_card-inner {
  transform: rotateY(180deg);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;perspective&lt;/span&gt;와 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;transform-style: preserve-3d&lt;/span&gt;입니다. 이 두 가지가 빠지면 앞&amp;middot;뒷면이 평면처럼 겹쳐 보이고, 카드가 진짜 뒤집히는 느낌이 사라집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example5&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 순수 CSS 로딩 스피너(Loading Spinner)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 응답 대기, 페이지 전환 등에서 &amp;ldquo;지금 처리 중&amp;rdquo;임을 알려 주는 기본 로딩 패턴입니다. 이미지 없이 CSS만으로 구현하면 테마 색상을 변경하기도 쉽고, 해상도 걱정도 없습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_loader {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 4px solid #e5e7eb;
  border-top-color: #4f46e5;
  animation: csspoststyle_spin 1s linear infinite;
}

@keyframes csspoststyle_spin {
  to {
    transform: rotate(360deg);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테두리 전체에는 옅은 회색, 윗부분만 강조 색을 주고 회전시키면 심플한 로딩 인디케이터가 됩니다. 웹사이 브랜드 컬러에 맞춰 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;border-top-color&lt;/span&gt;만 교체해서 사용해 보세요.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example6&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. 시선 집중 회전 효과 (뱅글뱅글 아이콘)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;지금 확인하기&amp;rdquo;, &amp;ldquo;신규&amp;rdquo; 같은 배지에 회전 애니메이션을 추가하면 사용자의 시선을 자연스럽게 끌어올 수 있습니다. 너무 크지 않은 아이콘에만 적용하는 것이 포인트입니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_rotate {
  display: inline-block;
  animation: csspoststyle_rotate360 2s linear infinite;
}

@keyframes csspoststyle_rotate360 {
  to {
    transform: rotate(360deg);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;속도를 1초 이하로 줄이면 너무 빠르게 느껴질 수 있으니, 2초 전후의 여유 있는 속도가 가장 무난합니다. 필요하다면 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;:hover&lt;/span&gt; 상태에서만 회전하도록 바꿔 사용해도 좋습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example7&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 맥박(Pulse) 효과로 중요한 요소 강조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심장 박동처럼 살짝 커졌다 줄어드는 맥박 효과는 가입 버튼, 알림 뱃지, 새 글 표시 등 &amp;ldquo;계속 눈에 띄어야 하는 요소&amp;rdquo;에 잘 어울립니다. 과하게 사용하지만 않으면 UX를 해치지 않으면서 클릭률을 높일 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_pulse {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  animation: csspoststyle_pulse-keyframes 1.5s ease-in-out infinite;
}

@keyframes csspoststyle_pulse-keyframes {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 1.05~1.1배 정도면 충분합니다. 1.2배 이상으로 키우면 강조는 잘 되지만, 화면 전체가 불안정하게 느껴질 수 있으니 주의하세요.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example8&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8. 스켈레톤 로딩(Skeleton Loading) 효과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 콘텐츠가 로딩될 때까지 빈 화면 대신 회색 뼈대 레이아웃을 먼저 보여 주는 패턴입니다. 특히 카드형 목록, 피드, 블로그 글 목록 등에서 &amp;ldquo;곧 내용이 채워질 것&amp;rdquo;이라는 인상을 줄 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_skeleton {
  border-radius: 10px;
  background: linear-gradient(
    90deg,
    #e5e7eb 25%,
    #d1d5db 50%,
    #e5e7eb 75%
  );
  background-size: 200% 100%;
  animation: csspoststyle_shimmer 1.5s infinite;
}

@keyframes csspoststyle_shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 카드 레이아웃과 비슷한 크기의 스켈레톤 박스를 여러 개 배치해 두면, 사용자는 로딩 중에도 전체 구조를 미리 파악할 수 있어 이탈률이 줄어듭니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example9&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9. 흔들림(Shake) 애니메이션으로 오류 피드백 제공&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인, 회원가입, 댓글 작성 폼 등에서 잘못된 입력이 발생했을 때 입력창을 좌우로 살짝 흔들면, 사용자에게 &amp;ldquo;여기에 문제가 있다&amp;rdquo;는 메시지를 직관적으로 전달할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_shake {
  animation: csspoststyle_shake-keyframes 0.5s ease;
}

@keyframes csspoststyle_shake-keyframes {
  0%,
  100% {
    transform: translateX(0);
  }
  20%,
  60% {
    transform: translateX(-10px);
  }
  40%,
  80% {
    transform: translateX(10px);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 오류가 발생했을 때만 자바스크립트로 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;csspoststyle_shake&lt;/span&gt; 클래스를 잠깐 넣었다가 애니메이션이 끝나면 제거하는 방식으로 사용합니다. 시각적인 피드백과 함께 에러 메시지도 같이 보여 주면 UX가 훨씬 좋아집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;csspoststyle_example10&quot; class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;10. 배경 및 텍스트 컬러 애니메이션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 분위기를 바꿔 주는 배경&amp;middot;텍스트 색상 애니메이션입니다. 헤더 영역, 히어로 섹션, 사이트 로고 영역 등에 천천히 색이 변하는 효과를 주면, 페이지가 정적인 느낌에서 살아 있는 느낌으로 바뀝니다.&lt;/p&gt;
&lt;div class=&quot;csspoststyle_code-block&quot;&gt;
&lt;div class=&quot;csspoststyle_code-header&quot;&gt;
&lt;div class=&quot;csspoststyle_code-dots&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span class=&quot;csspoststyle_code-label&quot;&gt;CSS&lt;/span&gt; &lt;button class=&quot;csspoststyle_code-copy&quot; type=&quot;button&quot;&gt;코드 복사&lt;/button&gt;&lt;/div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.csspoststyle_bg-change {
  animation: csspoststyle_change-bg 5s ease-in-out infinite alternate;
}

@keyframes csspoststyle_change-bg {
  0% {
    background-color: #ff6b6b;
  }
  100% {
    background-color: #feca57;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;csspoststyle_inline-code&quot;&gt;alternate&lt;/span&gt; 덕분에 색상이 시작색에서 끝색으로 갔다가 다시 시작색으로 자연스럽게 되돌아옵니다. 텍스트에 적용할 때는 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;background-clip: text&lt;/span&gt;와 그라디언트를 조합해 그라디언트 텍스트 애니메이션을 만들 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;csspoststyle_consider&quot; data-ke-size=&quot;size26&quot;&gt;CSS 애니메이션 적용 시 꼭 체크해야 할 사항&lt;/h2&gt;
&lt;div class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 성능 최적화&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가능하면 &lt;b&gt;transform&lt;/b&gt;과 &lt;b&gt;opacity&lt;/b&gt;만 애니메이션에 사용해 레이아웃 재계산을 줄입니다.&lt;/li&gt;
&lt;li&gt;리스트에 수십 개의 애니메이션을 동시에 돌리기보다는, 시차를 두거나 꼭 필요한 요소만 움직이도록 설계합니다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;csspoststyle_inline-code&quot;&gt;will-change&lt;/span&gt; 속성은 정말 성능 이슈가 확인된 요소에만 사용하고, 애니메이션이 끝난 뒤에는 제거해 메모리 사용량을 관리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 접근성과 사용자 배려&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일부 사용자는 강한 모션에 멀미&amp;middot;두통을 느낍니다. 운영체제의 모션 감소 설정을 반영하도록 &lt;span class=&quot;csspoststyle_inline-code&quot;&gt;@media (prefers-reduced-motion: reduce)&lt;/span&gt;를 고려해 보세요.&lt;/li&gt;
&lt;li&gt;이 모드에서는 무한 반복 애니메이션은 꺼 두고, 중요한 전환만 짧은 트랜지션으로 처리하는 식으로 대신할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) CSS 애니메이션과 JS 애니메이션의 역할 분리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단순 상태 전환, 반복되는 장식 효과는 CSS 애니메이션이 적합합니다. 선언형 방식이라 브라우저가 최적화하기 쉽습니다.&lt;/li&gt;
&lt;li&gt;스크롤 위치에 따라 변하는 패럴랙스, 드래그에 따라 움직이는 카드, 물리 엔진이 필요한 복잡한 모션은 JS 또는 Web Animations API, GSAP 같은 라이브러리를 고려합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) 사이트에 적용할 때의 실전 팁&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;글 상단: 페이드인과 슬라이드 업을 조합해 타이틀&amp;middot;썸네일을 자연스럽게 등장시키기&lt;/li&gt;
&lt;li&gt;코드 박스: 호버 시 살짝 확대되는 카드 효과로 &amp;ldquo;복사하기 버튼&amp;rdquo;이 더 잘 보이게 만들기&lt;/li&gt;
&lt;li&gt;로딩이 긴 페이지: 로딩 스피너와 스켈레톤 UI를 함께 사용해 사용자의 체감 대기 시간을 줄이기&lt;/li&gt;
&lt;li&gt;신규 기능 배지: 맥박 애니메이션으로 새 기능&amp;middot;이벤트 영역에 시선 집중시키기&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;csspoststyle_deeplink&quot; data-ke-size=&quot;size26&quot;&gt;더 깊이 공부할 수 있는 공식 문서와 추천 글&lt;/h2&gt;
&lt;div class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 공식 문서&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Animations/Using_CSS_animations&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MDN Web Docs &amp;ndash; CSS 애니메이션 사용법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/transition&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MDN Web Docs &amp;ndash; CSS transition 속성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MDN Web Docs &amp;ndash; prefers-reduced-motion 미디어 쿼리&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;csspoststyle_section&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 정리가 잘 된 해외 레퍼런스&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://css-tricks.com/almanac/properties/a/animation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CSS-Tricks &amp;ndash; A Complete Guide to CSS Animation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/animations-guide/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;web.dev &amp;ndash; Animation Guide for the Web&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 문서들은 최신 브라우저 기준으로 정리되어 있어, 실제 사이트 애니메이션을 설계할 때 큰 도움이 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 설계된 CSS 애니메이션은 웹사이트의 완성도를 한 단계 끌어올려 주지만, 과도하게 사용하면 오히려 콘텐츠를 방해할 수 있습니다. 이 글에서 정리한 10가지 패턴과 가이드를 기반으로, 자신의 서비스에 맞는 효과만 선택해서 적용해 보세요.&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;ldquo;조금만 잘 움직이는&amp;rdquo; 섬세한 애니메이션이 신뢰감을 높여 줍니다. 애니메이션을 항상 &lt;b&gt;콘텐츠를 돕는 조연&lt;/b&gt;으로 생각한다면, UX&amp;middot;성능&amp;middot;접근성 사이에서 좋은 균형을 잡을 수 있을 것입니다.&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; CSS, CSS 애니메이션, 웹 디자인, UI/UX, 프론트엔드, 웹 애니메이션, 키프레임, 트랜지션, 인터랙션, 웹 퍼포먼스&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
function csspoststyle_initCopyButtons() {
  var csspoststyle_blocks = document.querySelectorAll(&quot;.csspoststyle_code-block&quot;);
  csspoststyle_blocks.forEach(function (csspoststyle_block) {
    var csspoststyle_button = csspoststyle_block.querySelector(&quot;.csspoststyle_code-copy&quot;);
    var csspoststyle_codeElement = csspoststyle_block.querySelector(&quot;pre code&quot;);
    if (!csspoststyle_button || !csspoststyle_codeElement) {
      return;
    }
    csspoststyle_button.addEventListener(&quot;click&quot;, function () {
      var csspoststyle_text = csspoststyle_codeElement.innerText;
      if (navigator.clipboard &amp;&amp; navigator.clipboard.writeText) {
        navigator.clipboard.writeText(csspoststyle_text).then(function () {
          csspoststyle_showToast(&quot;코드를 복사했습니다.&quot;);
        }).catch(function () {
          csspoststyle_fallbackCopy(csspoststyle_text);
        });
      } else {
        csspoststyle_fallbackCopy(csspoststyle_text);
      }
    });
  });
}
function csspoststyle_fallbackCopy(csspoststyle_text) {
  var csspoststyle_textarea = document.createElement(&quot;textarea&quot;);
  csspoststyle_textarea.value = csspoststyle_text;
  csspoststyle_textarea.style.position = &quot;fixed&quot;;
  csspoststyle_textarea.style.left = &quot;-9999px&quot;;
  document.body.appendChild(csspoststyle_textarea);
  csspoststyle_textarea.focus();
  csspoststyle_textarea.select();
  try {
    document.execCommand(&quot;copy&quot;);
    csspoststyle_showToast(&quot;코드를 복사했습니다.&quot;);
  } catch (csspoststyle_error) {
    csspoststyle_showToast(&quot;복사에 실패했습니다. 수동으로 복사해주세요.&quot;);
  }
  document.body.removeChild(csspoststyle_textarea);
}
function csspoststyle_showToast(csspoststyle_message) {
  var csspoststyle_toast = document.createElement(&quot;div&quot;);
  csspoststyle_toast.className = &quot;csspoststyle_toast&quot;;
  csspoststyle_toast.textContent = csspoststyle_message;
  document.body.appendChild(csspoststyle_toast);
  setTimeout(function () {
    if (csspoststyle_toast &amp;&amp; csspoststyle_toast.parentNode) {
      csspoststyle_toast.parentNode.removeChild(csspoststyle_toast);
    }
  }, 2500);
}
document.addEventListener(&quot;DOMContentLoaded&quot;, csspoststyle_initCopyButtons);
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>css</category>
      <category>CSS 애니메이션 성능 최적화</category>
      <category>CSS 애니메이션 예제</category>
      <category>CSS 트랜지션</category>
      <category>애니메이션</category>
      <category>웹 애니메이션 접근성</category>
      <category>웹디자인</category>
      <category>웹사이트 모션 효과</category>
      <category>키프레임 애니메이션</category>
      <category>프론트엔드 애니메이션 기법</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/560</guid>
      <comments>https://odinbox.tistory.com/560#entry560comment</comments>
      <pubDate>Sat, 22 Nov 2025 19:30:19 +0900</pubDate>
    </item>
    <item>
      <title>PFU HHKB Professional HYBRID Type-S</title>
      <link>https://odinbox.tistory.com/559</link>
      <description>&lt;div&gt;
&lt;style&gt;
.hhkb_post-root {
  max-width: 980px;
  margin: 0 auto 40px;
  padding: 24px 20px 40px;
  box-sizing: border-box;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;
  color: #f9fafb;
  background: #020617;
  border-radius: 24px;
  box-shadow: 0 28px 80px rgba(15, 23, 42, 0.85);
}

/* 기본 링크 스타일 */
.hhkb_post-root a {
  color: #38bdf8;
  text-decoration: none;
}
.hhkb_post-root a:hover {
  text-decoration: underline;
}

/* 본문 텍스트 색 강제 (티스토리 기본 스타일 덮어쓰기) */
.hhkb_post-root p,
.hhkb_post-root p *,
.hhkb_post-root li,
.hhkb_post-root li * {
  color: #e5e7eb !important;
}

/* 인라인 코드 색상 */
.hhkb_post-root code {
  padding: 1px 4px;
  border-radius: 4px;
  background: rgba(15, 23, 42, 0.9);
  color: #fb923c !important;
  font-size: 0.9em;
}

/* 제목들 */
.hhkb_post-root h1,
.hhkb_post-root h2,
.hhkb_post-root h3 {
  margin: 0 0 16px;
  font-weight: 700;
  color: #f9fafb;
}
.hhkb_post-root h1 {
  font-size: 2.1rem;
  line-height: 1.3;
}
.hhkb_post-root h2 {
  font-size: 1.5rem;
  margin-top: 40px;
}
.hhkb_post-root h3 {
  font-size: 1.1rem;
  margin-top: 24px;
}

/* 문단 */
.hhkb_post-root p {
  margin: 0 0 14px;
  line-height: 1.7;
  font-size: 0.98rem;
}

/* 리스트 */
.hhkb_post-root ul {
  margin: 4px 0 16px 1.3rem;
  padding: 0;
}
.hhkb_post-root li {
  margin-bottom: 6px;
  font-size: 0.95rem;
}

/* 헤더 카드 */
.hhkb_hero {
  background: radial-gradient(circle at top left, #0b1120 0, #020617 55%, #020617 100%);
  color: #f9fafb;
  border-radius: 22px;
  padding: 22px 20px 20px;
  margin-bottom: 24px;
  box-shadow: 0 24px 50px rgba(15, 23, 42, 0.9);
  position: relative;
  overflow: hidden;
}
.hhkb_hero::before {
  content: &quot;&quot;;
  position: absolute;
  inset: -40%;
  background:
    radial-gradient(circle at 10% 0%, rgba(96, 165, 250, 0.35) 0, transparent 55%),
    radial-gradient(circle at 90% 100%, rgba(248, 250, 252, 0.16) 0, transparent 50%);
  z-index: 0;
}
.hhkb_hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2.1fr);
  gap: 18px;
  align-items: center;
}
.hhkb_hero-text-main {
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: #9ca3af;
  margin-bottom: 10px;
}
.hhkb_hero-title {
  font-size: 1.8rem;
  line-height: 1.35;
  margin-bottom: 10px;
  color: #f9fafb;
}
.hhkb_hero-subtitle {
  font-size: 0.95rem;
  color: #d1d5db;
  margin-bottom: 10px;
}
.hhkb_hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
  font-size: 0.8rem;
  color: #9ca3af;
}
.hhkb_hero-meta-badge {
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.55);
  padding: 4px 10px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(15, 23, 42, 0.96);
  backdrop-filter: blur(10px);
}
.hhkb_hero-badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: #22c55e;
  box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.35);
}

/* 썸네일 카드 */
.hhkb_hero-thumb {
  border-radius: 16px;
  background: #020617;
  padding: 10px;
  border: 1px solid rgba(148, 163, 184, 0.7);
  position: relative;
  overflow: hidden;
}
.hhkb_hero-thumb-inner {
  border-radius: 10px;
  overflow: hidden;
  background: #020617;
}
.hhkb_hero-thumb-caption {
  font-size: 0.78rem;
  color: #cbd5f5;
  margin-top: 6px;
  text-align: right;
}

/* 상단 해시태그 */
.hhkb_tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 24px;
}
.hhkb_tag-pill {
  font-size: 0.82rem;
  padding: 5px 12px;
  border-radius: 999px;
  background: #020617;
  border: 1px solid #1f2937;
  color: #e5e7eb;
  box-shadow: 0 10px 20px rgba(15, 23, 42, 0.9);
}
.hhkb_tag-pill:hover {
  background: #111827;
}

/* 카드 / 목차 */
.hhkb_main {
  min-width: 0;
}
.hhkb_card {
  background: #020617;
  border-radius: 16px;
  padding: 16px 16px 14px;
  box-shadow: 0 16px 30px rgba(15, 23, 42, 0.9);
  border: 1px solid #1f2937;
  margin-bottom: 20px;
}
.hhkb_card-title {
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 8px;
  color: #f9fafb;
}
.hhkb_card-sub {
  font-size: 0.78rem;
  color: #9ca3af;
  margin-bottom: 8px;
}
.hhkb_toc-list {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 0.86rem;
}
.hhkb_toc-list li {
  margin-bottom: 4px;
}
.hhkb_toc-link {
  cursor: pointer;
  color: #e5e7eb;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  border-radius: 6px;
  transition: background 0.18s ease, transform 0.18s ease, color 0.18s ease;
}
.hhkb_toc-link-dot {
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: #6b7280;
}
.hhkb_toc-link:hover {
  background: #111827;
  transform: translateX(2px);
  color: #f9fafb;
}

/* 스펙 테이블 */
.hhkb_spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
  margin: 6px 0 18px;
  background: #020617;
  border-radius: 12px;
  overflow: hidden;
}
.hhkb_spec-table th,
.hhkb_spec-table td {
  padding: 7px 10px;
  border-bottom: 1px solid #111827;
}
.hhkb_spec-table th {
  width: 26%;
  background: #020617;
  text-align: left;
  font-weight: 600;
  color: #cbd5f5;
}
.hhkb_spec-table td {
  color: #e5e7eb;
}

/* 이미지 블록 */
.hhkb_image-block {
  margin: 18px 0 16px;
  text-align: center;
}
.hhkb_image-inner {
  border-radius: 18px;
  overflow: hidden;
  background: #020617;
  padding: 10px;
  box-shadow: 0 22px 45px rgba(15, 23, 42, 0.95);
  border: 1px solid #0f172a;
}
.hhkb_image-caption {
  font-size: 0.8rem;
  color: #f9fafb;
  margin-top: 6px;
}

/* 하이라이트 박스 */
.hhkb_highlight {
  margin: 18px 0;
  border-radius: 14px;
  padding: 14px 14px 12px;
  background: linear-gradient(135deg, #1e293b, #020617);
  border: 1px solid #334155;
  font-size: 0.9rem;
}
.hhkb_highlight-title {
  font-weight: 700;
  font-size: 0.9rem;
  margin-bottom: 4px;
  color: #bfdbfe;
}

/* 하단 태그 */
.hhkb_tag-footer {
  margin-top: 32px;
  padding-top: 16px;
  border-top: 1px solid #111827;
}
.hhkb_tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.hhkb_tag-chip {
  font-size: 0.82rem;
  padding: 5px 12px;
  border-radius: 999px;
  background: #020617;
  border: 1px solid #1f2937;
  color: #e5e7eb;
  box-shadow: 0 10px 22px rgba(15, 23, 42, 0.9);
}
.hhkb_tag-chip:hover {
  background: #111827;
}

/* 버튼 */
.hhkb_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 0.88rem;
  font-weight: 600;
  border: none;
  outline: none;
  cursor: pointer;
  background: linear-gradient(135deg, #22c55e, #16a34a);
  color: #f9fafb;
  box-shadow: 0 12px 25px rgba(22, 163, 74, 0.6);
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.hhkb_button:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 35px rgba(22, 163, 74, 0.7);
  filter: brightness(1.03);
}
.hhkb_button span.hhkb_button-icon {
  font-size: 1.05em;
}

/* 공통 호버 애니메이션 */
.hhkb_animate {
  transition: transform 0.45s ease, box-shadow 0.45s ease;
}
.hhkb_animate:hover {
  transform: translateY(-1px);
}

/* 반응형 */
@media (max-width: 900px) {
  .hhkb_hero-inner {
    grid-template-columns: minmax(0, 1.7fr);
  }
}
@media (max-width: 600px) {
  .hhkb_post-root {
    padding: 16px 12px 32px;
  }
  .hhkb_hero {
    padding: 18px 14px 16px;
  }
  .hhkb_hero-title {
    font-size: 1.5rem;
  }
}
&lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_post-root&quot;&gt;
&lt;section class=&quot;hhkb_hero hhkb_animate&quot; data-hhkb-section=&quot;top&quot;&gt;
&lt;div class=&quot;hhkb_hero-inner&quot;&gt;
&lt;div&gt;
&lt;div class=&quot;hhkb_hero-text-main&quot;&gt;DEVELOPER KEYBOARD REVIEW&lt;/div&gt;
&lt;h1 class=&quot;hhkb_hero-title&quot;&gt;HHKB Hybrid&lt;br /&gt;Professional Type-S&lt;br /&gt;하루 종일 코딩하는 개발자의 실사용 리뷰&lt;/h1&gt;
&lt;p class=&quot;hhkb_hero-subtitle&quot; data-ke-size=&quot;size16&quot;&gt;일본 직구, 첫 제품 불량 교환, 그리고 이제는 메인 키보드가 된 HHKB Type-S. 유선&amp;middot;무선 하이브리드, 무접점 키감, DIP 스위치와 키맵핑까지 한 번에 정리합니다.&lt;/p&gt;
&lt;div class=&quot;hhkb_hero-meta&quot;&gt;
&lt;div class=&quot;hhkb_hero-meta-badge&quot;&gt;&lt;span class=&quot;hhkb_hero-badge-dot&quot;&gt;&lt;/span&gt; &lt;span&gt;하루 대부분을 키보드 위에서 보내는 개발자의 관점&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;hhkb_hero-meta-badge&quot;&gt;&lt;span&gt;무접점 &amp;middot; 하이브리드 &amp;middot; 60% 레이아웃&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_hero-thumb&quot;&gt;
&lt;div class=&quot;hhkb_hero-thumb-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2csEW/dJMcajtNed4/FFIZxa19AGKp1VZoAf7UJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2csEW/dJMcajtNed4/FFIZxa19AGKp1VZoAf7UJ1/img.png&quot; data-alt=&quot;썸네일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2csEW/dJMcajtNed4/FFIZxa19AGKp1VZoAf7UJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2csEW%2FdJMcajtNed4%2FFFIZxa19AGKp1VZoAf7UJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;썸네일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_hero-thumb-caption&quot;&gt;데스크 한 켠을 책임지는 메인 키보드, HHKB Hybrid Professional Type-S&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;div class=&quot;hhkb_tag-row hhkb_animate&quot;&gt;&lt;span class=&quot;hhkb_tag-pill&quot;&gt;#HHKB&lt;/span&gt; &lt;span class=&quot;hhkb_tag-pill&quot;&gt;#해피해킹&lt;/span&gt; &lt;span class=&quot;hhkb_tag-pill&quot;&gt;#개발자키보드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-pill&quot;&gt;#무접점키보드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-pill&quot;&gt;#HybridTypeS&lt;/span&gt;&lt;/div&gt;
&lt;main class=&quot;hhkb_main&quot;&gt;
&lt;div class=&quot;hhkb_card hhkb_animate&quot;&gt;
&lt;div class=&quot;hhkb_card-title&quot;&gt;목차&lt;/div&gt;
&lt;div class=&quot;hhkb_card-sub&quot;&gt;궁금한 부분부터 바로 읽어보세요. (H2/H3 기준, 티스토리 자동 목차도 함께 생성됩니다.)&lt;/div&gt;
&lt;ul class=&quot;hhkb_toc-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;intro&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 서론 &amp;ndash; 왜 HHKB인가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;specs&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 제품 정보 요약&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;unboxing&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 개봉기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;design&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 디자인 &amp;amp; 구조&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;review&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 사용 후기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;settings&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 설정 팁 (블루투스&amp;middot;DIP&amp;middot;키맵)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;hhkb_toc-link&quot; data-hhkb-target=&quot;conclusion&quot;&gt;&lt;span class=&quot;hhkb_toc-link-dot&quot;&gt;&lt;/span&gt; 마무리 &amp;amp; 추천 대상&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;section id=&quot;hhkb_intro&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;intro&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;서론 &amp;ndash; 왜 하필 HHKB였을까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 직업상 하루 대부분을 IDE와 터미널 앞에서 보내는 개발자입니다. 그래서 마우스보다 키보드를 더 많이 쓰고, 자연스럽게 키보드에 대한 욕심도 커졌습니다. 체리 스위치 계열의 기계식, 저소음 적축, 펜타그래프까지 여러 종류를 써봤지만 항상 &amp;ldquo;조금만 더 조용했으면&amp;hellip;&amp;rdquo;, &amp;ldquo;손 이동이 조금만 덜했으면&amp;hellip;&amp;rdquo; 하는 아쉬움이 남았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 커뮤니티와 유튜브, 블로그를 돌다 보면 반드시 한 번은 마주치는 이름이 있습니다. 바로 &lt;b&gt;HHKB(Happy Hacking Keyboard)&lt;/b&gt;. 키 개수도 적고, 방향키도 없고, 일반 배열과는 많이 다른데도 많은 개발자들이 &amp;ldquo;결국은 HHKB로 돌아온다&amp;rdquo;라는 말을 남기더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은 60% 배열이라 처음엔 불편할 것 같았지만, &lt;b&gt;Topre 무접점 스위치 + 하이브리드(유선&amp;middot;무선) + OS 전환 + DIP 스위치&lt;/b&gt;라는 조합이 계속 머릿속에 남았습니다. 결국 일본 직구로 &lt;b&gt;HHKB Hybrid Professional Type-S&lt;/b&gt;를 주문했고, 첫 제품은 안타깝게도 흔들면 이물질 굴러가는 듯한 소리가 나서 교환까지 겪었습니다. 하지만 교환 후 받은 제품은 지금까지 제 메인 키보드로 자리를 완전히 잡았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 처음 도착한 박스부터 실제 설정 및 사용, 그리고 개발자로서 느낀 장단점까지 한 번에 정리해보려고 합니다. HHKB를 고민하는 분들께 기준점이 되었으면 합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;hhkb_specs&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;specs&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;제품 정보 &amp;ndash; HHKB Hybrid Professional Type-S 한눈에 보기&lt;/h2&gt;
&lt;div class=&quot;hhkb_highlight&quot;&gt;
&lt;div class=&quot;hhkb_highlight-title&quot;&gt;요약&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HHKB Hybrid Professional Type-S는 &lt;b&gt;무접점 토프레 스위치&lt;/b&gt; 기반의 &lt;b&gt;60% 컴팩트 배열&lt;/b&gt; 키보드로, &lt;b&gt;블루투스 4대 멀티 페어링 + USB-C 유선&lt;/b&gt;을 동시에 지원하는 하이브리드 모델입니다. Type-S는 &amp;lsquo;Silent&amp;rsquo; 버전으로, 기본 HHKB보다 타건 소음을 눈에 띄게 줄여줍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;hhkb_spec-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;모델명&lt;/th&gt;
&lt;td&gt;HHKB Professional HYBRID Type-S (무접점, 저소음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;스위치&lt;/th&gt;
&lt;td&gt;정전용량 무접점 Topre, 약 45g, Type-S 저소음 튜닝&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;배열&lt;/th&gt;
&lt;td&gt;60% 컴팩트 배열, HHKB 고유 레이아웃 (Control 홈포지션, 방향키 레이어)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;연결&lt;/th&gt;
&lt;td&gt;Bluetooth 최대 4대 멀티 페어링, USB-C 유선 연결&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;지원 OS&lt;/th&gt;
&lt;td&gt;Windows / macOS / iOS / Android (DIP 스위치로 Mac/Win 모드 전환)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;전원&lt;/th&gt;
&lt;td&gt;AA 건전지 2개 (블루투스), USB-C 연결 시 외부 전원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;키캡&lt;/th&gt;
&lt;td&gt;PBT 소재, 염료승화 각인, 내구성이 높고 번들거림이 적음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;td&gt;키맵핑 소프트웨어 지원, DIP 스위치, 절전 모드, 컨트롤/캡스락 위치 최적화&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id=&quot;hhkb_unboxing&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;unboxing&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개봉기 &amp;ndash; 일본에서 온 작은 패키지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HHKB Hybrid Type-S는 일본 직구로 주문했습니다. 생각보다 작은 택배 박스 안에 또 한 번의 박스, 그리고 그 안에 정갈하게 포장된 키보드가 들어있었습니다. 패키징은 전체적으로 &amp;ldquo;과하지 않게, 딱 필요한 만큼&amp;rdquo;이라는 느낌이 강했습니다.&lt;/p&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y5Dsj/dJMcahpcWLX/MzJrunRGdtO1TKLYkshHcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y5Dsj/dJMcahpcWLX/MzJrunRGdtO1TKLYkshHcK/img.png&quot; data-alt=&quot;제품도착직후포장박스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y5Dsj/dJMcahpcWLX/MzJrunRGdtO1TKLYkshHcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY5Dsj%2FdJMcahpcWLX%2FMzJrunRGdtO1TKLYkshHcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제품도착직후포장박스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;일본에서 도착한 첫 박스. 예상보다 작고 단단하게 포장되어 있었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGei0M/dJMcaap474A/5fE23H0kVYx4wl0fLYEjok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGei0M/dJMcaap474A/5fE23H0kVYx4wl0fLYEjok/img.png&quot; data-alt=&quot;제품상자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGei0M/dJMcaap474A/5fE23H0kVYx4wl0fLYEjok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGei0M%2FdJMcaap474A%2F5fE23H0kVYx4wl0fLYEjok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제품상자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;겉 포장을 벗기면 나오는 HHKB 전용 박스. 군더더기 없는 디자인입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGhb6a/dJMcadUD6mS/vgE29POsMt1YPSdkLKy6q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGhb6a/dJMcadUD6mS/vgE29POsMt1YPSdkLKy6q0/img.png&quot; data-alt=&quot;제품온직후배송박스안물품&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGhb6a/dJMcadUD6mS/vgE29POsMt1YPSdkLKy6q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGhb6a%2FdJMcadUD6mS%2FvgE29POsMt1YPSdkLKy6q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제품온직후배송박스안물품&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;배송 박스 속 본품 박스와 보호재. 충격에 대비한 패킹이 잘 되어 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1hMvj/dJMcaap474B/V73vMJ8bJEWv1dDSsQnkI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1hMvj/dJMcaap474B/V73vMJ8bJEWv1dDSsQnkI1/img.png&quot; data-alt=&quot;제품상자개봉직후모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1hMvj/dJMcaap474B/V73vMJ8bJEWv1dDSsQnkI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1hMvj%2FdJMcaap474B%2FV73vMJ8bJEWv1dDSsQnkI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제품상자개봉직후모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;박스를 열면 키보드 본체가 안전하게 고정되어 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPFlky/dJMcahpcWLY/ziiJpaJIHKaahkSX8R0rs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPFlky/dJMcahpcWLY/ziiJpaJIHKaahkSX8R0rs1/img.png&quot; data-alt=&quot;제품구성품&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPFlky/dJMcahpcWLY/ziiJpaJIHKaahkSX8R0rs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPFlky%2FdJMcahpcWLY%2FziiJpaJIHKaahkSX8R0rs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제품구성품&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;구성품: 키보드 본체, AA 배터리, 설명서 등. 심플하지만 필요한 건 다 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dguSrN/dJMcahpcWLW/VRA5lt9fSMs5LoKvBpIFvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dguSrN/dJMcahpcWLW/VRA5lt9fSMs5LoKvBpIFvk/img.png&quot; data-alt=&quot;키보드박스뒷면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dguSrN/dJMcahpcWLW/VRA5lt9fSMs5LoKvBpIFvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdguSrN%2FdJMcahpcWLW%2FVRA5lt9fSMs5LoKvBpIFvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드박스뒷면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;박스 뒷면에는 간단한 사양과 시리얼이 표기되어 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tu6Za/dJMcaacATdG/uX92khLQqn5kHjQkd5krI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tu6Za/dJMcaacATdG/uX92khLQqn5kHjQkd5krI1/img.png&quot; data-alt=&quot;키보드박스옆면1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tu6Za/dJMcaacATdG/uX92khLQqn5kHjQkd5krI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTu6Za%2FdJMcaacATdG%2FuX92khLQqn5kHjQkd5krI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드박스옆면1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;박스 옆면1 &amp;ndash; 모델명과 브랜드 로고.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnWa1G/dJMcabP6FES/aqralvH6mqu4i68ky3TuQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnWa1G/dJMcabP6FES/aqralvH6mqu4i68ky3TuQ0/img.png&quot; data-alt=&quot;키보드박스옆면2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnWa1G/dJMcabP6FES/aqralvH6mqu4i68ky3TuQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnWa1G%2FdJMcabP6FES%2FaqralvH6mqu4i68ky3TuQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드박스옆면2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;박스 옆면2 &amp;ndash; 하이브리드(Type-S) 모델 표시.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buPSlD/dJMcaeMMMRJ/n9VJkvhEjuQ36F58dgNF8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buPSlD/dJMcaeMMMRJ/n9VJkvhEjuQ36F58dgNF8K/img.png&quot; data-alt=&quot;키보드박스옆면3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buPSlD/dJMcaeMMMRJ/n9VJkvhEjuQ36F58dgNF8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuPSlD%2FdJMcaeMMMRJ%2Fn9VJkvhEjuQ36F58dgNF8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드박스옆면3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;박스 옆면3 &amp;ndash; 간단한 마케팅 문구와 스펙 요약.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;hhkb_design&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;design&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;디자인 &amp;ndash; 작은 키보드, 꽉 찬 활용성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드 본체는 무광스러운 하우징과 PBT 키캡이 조합된, 전형적인 &amp;ldquo;해피해킹&amp;rdquo; 느낌의 디자인입니다. 상단 왼쪽 HHKB 로고, 키캡의 각인, 살짝 높게 솟은 실루엣이 전체적으로 깔끔한 인상을 줍니다.&lt;/p&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPW4is/dJMcaboZqeC/erSl6D2M2aP29jaVpdnBD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPW4is/dJMcaboZqeC/erSl6D2M2aP29jaVpdnBD0/img.png&quot; data-alt=&quot;키보드USB-C타입포트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPW4is/dJMcaboZqeC/erSl6D2M2aP29jaVpdnBD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPW4is%2FdJMcaboZqeC%2FerSl6D2M2aP29jaVpdnBD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드USB-C타입포트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;USB-C 포트 &amp;ndash; 집에서는 유선, 외부에서는 무선으로 사용하기 좋습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b34Oue/dJMcaksHrQY/ywiOqYTiylCySa7Ft9NaHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b34Oue/dJMcaksHrQY/ywiOqYTiylCySa7Ft9NaHK/img.png&quot; data-alt=&quot;DPI설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b34Oue/dJMcaksHrQY/ywiOqYTiylCySa7Ft9NaHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb34Oue%2FdJMcaksHrQY%2FywiOqYTiylCySa7Ft9NaHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DPI설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;뒷면 DIP 스위치 &amp;ndash; OS 모드, 키 위치, 절전 모드 등을 하드웨어 수준에서 설정합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRJu2G/dJMcadUD6mU/mtTljLuB9qzM0UYtZEnuBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRJu2G/dJMcadUD6mU/mtTljLuB9qzM0UYtZEnuBk/img.png&quot; data-alt=&quot;건전지넣는부분&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRJu2G/dJMcadUD6mU/mtTljLuB9qzM0UYtZEnuBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRJu2G%2FdJMcadUD6mU%2FmtTljLuB9qzM0UYtZEnuBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;건전지넣는부분&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;AA 건전지 2개를 넣는 부분. 블루투스 사용 시 전원을 담당합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4WLU2/dJMcaacATdd/2IMf1bi8M8KkrJ8XbA53qK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4WLU2/dJMcaacATdd/2IMf1bi8M8KkrJ8XbA53qK/img.png&quot; data-alt=&quot;키보드뒷면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4WLU2/dJMcaacATdd/2IMf1bi8M8KkrJ8XbA53qK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4WLU2%2FdJMcaacATdd%2F2IMf1bi8M8KkrJ8XbA53qK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드뒷면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;뒷면 전체 모습 &amp;ndash; 미끄럼 방지 패드와 높이 조절 다리가 보입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6tXeY/dJMcaeMMMRI/xjRsyFJo7UdcZftgaPfqz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6tXeY/dJMcaeMMMRI/xjRsyFJo7UdcZftgaPfqz1/img.png&quot; data-alt=&quot;키보드모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6tXeY/dJMcaeMMMRI/xjRsyFJo7UdcZftgaPfqz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6tXeY%2FdJMcaeMMMRI%2FxjRsyFJo7UdcZftgaPfqz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;앞쪽에서 바라본 전체 모습. 방향키는 레이어 조합으로 대신합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEshOD/dJMcaeMMMRH/rzO8RfUPskKpmln3PGokGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEshOD/dJMcaeMMMRH/rzO8RfUPskKpmln3PGokGK/img.png&quot; data-alt=&quot;키보드상단왼족제품로고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEshOD/dJMcaeMMMRH/rzO8RfUPskKpmln3PGokGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEshOD%2FdJMcaeMMMRH%2FrzO8RfUPskKpmln3PGokGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드상단왼족제품로고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;왼쪽 상단 제품 로고. 깔끔한 각인이 전체 인상을 결정합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdSvts/dJMcadUD6mW/XYoq3xsDKj3y8otQiYQ7oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdSvts/dJMcadUD6mW/XYoq3xsDKj3y8otQiYQ7oK/img.png&quot; data-alt=&quot;키보드옆면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdSvts/dJMcadUD6mW/XYoq3xsDKj3y8otQiYQ7oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdSvts%2FdJMcadUD6mW%2FXYoq3xsDKj3y8otQiYQ7oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드옆면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;옆에서 본 높이와 각도. 스텝드 스컬쳐 프로파일이라 손목이 편합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rHVQn/dJMcadUD6mT/z5RKsNtJbGruNVaEjvHpg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rHVQn/dJMcadUD6mT/z5RKsNtJbGruNVaEjvHpg0/img.png&quot; data-alt=&quot;키보드전원&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rHVQn/dJMcadUD6mT/z5RKsNtJbGruNVaEjvHpg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrHVQn%2FdJMcadUD6mT%2Fz5RKsNtJbGruNVaEjvHpg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드전원&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;전원 스위치. 물리 스위치라 우발적인 꺼짐/켜짐이 거의 없습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8WP4Z/dJMcaboZqez/FK5a9rbiMWKANX8ZomPamk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8WP4Z/dJMcaboZqez/FK5a9rbiMWKANX8ZomPamk/img.png&quot; data-alt=&quot;키보드키캡&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8WP4Z/dJMcaboZqez/FK5a9rbiMWKANX8ZomPamk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8WP4Z%2FdJMcaboZqez%2FFK5a9rbiMWKANX8ZomPamk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드키캡&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;키캡 클로즈업. PBT 특유의 보슬한 촉감이 좋고 각인은 또렷합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;hhkb_review&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;review&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사용 후기 &amp;ndash; 하루 종일 써도 손이 편한 키보드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 느낀 부분은 &lt;b&gt;타건감과 소음&lt;/b&gt;입니다. 일반 기계식(갈축, 적축, 저소음 적축 등)에 비해 Topre 무접점 스위치는 처음 눌렀을 때 살짝 말캉한 느낌이 있으면서도 확실한 입력감을 줍니다. Type-S는 여기에 저소음 튜닝이 들어가, 야간에도 부담 없이 사용할 수 있을 정도로 조용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키가 적기 때문에 손의 이동 범위가 줄어드는 점도 큰 장점입니다. 방향키, Home/End 같은 키들은 Fn 조합으로 대신하지만, &lt;b&gt;코딩할 때 가장 많이 쓰는 키들(Ctrl, Esc, 기호 키들)은 손이 거의 떠나지 않는 위치&lt;/b&gt;에 있습니다. 익숙해지는 데 2~3일 정도만 투자하면 오히려 일반 풀배열보다 효율적인 레이아웃이라는 생각이 듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞에서 이야기했듯이, 처음 받은 제품은 안쪽에서 뭔가 굴러다니는 소리가 나서 교환을 진행했습니다. 한 번 교환을 겪고 나니 &amp;ldquo;이 가격에 이런 QC가&amp;hellip;?&amp;rdquo; 라는 실망감도 살짝 들었지만, 교환 후 도착한 제품은 내부 소음 없이 매우 튼튼한 마감 상태를 보여 주었습니다. 이후로는 데일리 메인 키보드로 문제 없이 사용 중입니다.&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;손과 손목이 편한 타건감 (무접점 + 컴팩트 배열)&lt;/li&gt;
&lt;li&gt;Type-S 특유의 정숙함 &amp;ndash; 집/사무실/야간 작업 모두 무난&lt;/li&gt;
&lt;li&gt;Windows / macOS 모두 잘 맞는 OS 전환 및 키맵핑&lt;/li&gt;
&lt;li&gt;4대까지 페어링 되는 블루투스 + USB-C 유선 조합&lt;/li&gt;
&lt;li&gt;책상 위가 정말 깔끔해지는 작은 사이즈&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;가격 &amp;ndash; &amp;ldquo;키보드에 이렇게까지?&amp;rdquo; 라는 생각이 들 수 있는 수준&lt;/li&gt;
&lt;li&gt;처음 적응까지 2~3일 이상은 투자해야 함 (특히 방향키/Del/Fn 위치)&lt;/li&gt;
&lt;li&gt;정답이 없는 레이아웃이라 사람에 따라 극호/극불호가 갈릴 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;hhkb_settings&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;settings&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설정 팁 &amp;ndash; 블루투스, DIP 스위치, 키맵핑까지&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 블루투스 페어링 &amp;amp; 기기 전환&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집에서는 데스크톱(유선), 외부에서는 노트북&amp;middot;태블릿(무선) 조합으로 쓰고 있습니다. HHKB Hybrid Type-S는 최대 4대까지 페어링을 지원하기 때문에, 노트북, 태블릿, 스마트폰 등을 모두 등록해두고 필요할 때마다 전환할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전원 켜기: 뒤쪽 전원 스위치를 ON&lt;/li&gt;
&lt;li&gt;페어링 모드: 설명서 기준 조합(예: &lt;code&gt;Fn + Q&lt;/code&gt; 또는 &lt;code&gt;Fn + Ctrl + [숫자]&lt;/code&gt;)으로 진입&lt;/li&gt;
&lt;li&gt;기기 등록: OS에서 블루투스 &amp;rarr; &amp;lsquo;HHKB-Hybrid&amp;rsquo; 선택&lt;/li&gt;
&lt;li&gt;전환: 등록된 기기 간 전환은 &lt;code&gt;Fn + Ctrl + 1~4&lt;/code&gt; 같은 조합으로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. DIP 스위치 &amp;ndash; OS 모드와 기본 키 위치 바꾸기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HHKB 뒷면의 DIP 스위치에서는 &lt;b&gt;Windows / macOS 모드, Delete/Backspace 위치, Alt/Command 위치, 절전 모드&lt;/b&gt; 등을 설정할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;OS 모드&lt;/b&gt;: Mac 위주라면 Mac 모드로 두고, 회사 PC에서는 Windows 모드로 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Delete / Backspace 스왑&lt;/b&gt;: 기존 배열에 익숙하면 Delete 위치를 일반 키보드처럼 맞출 수 있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Alt / Command 위치 변경&lt;/b&gt;: macOS 단축키(Cmd+Space, Cmd+Tab 등)에 맞춰 자연스럽게 배치&lt;/li&gt;
&lt;li&gt;&lt;b&gt;절전 스위치&lt;/b&gt;: 몇 분 이상 입력이 없을 때 자동 슬립 &amp;rarr; 배터리 수명 연장&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 전원&amp;middot;절전 설정 팁&lt;/h3&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;블루투스 위주 사용이라면 DIP로 절전 시간을 짧게 설정해두면 배터리가 훨씬 오래갑니다.&lt;/li&gt;
&lt;li&gt;장기간 미사용 예정이라면 전원 스위치를 확실히 OFF로 두는 습관을 들이는 게 좋습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 키맵 툴 &amp;ndash; 나만의 HHKB 만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HHKB Hybrid Type-S는 &lt;b&gt;전용 키맵핑 소프트웨어&lt;/b&gt;를 제공합니다. USB-C로 PC에 연결한 뒤 아래와 같이 커스터마이징하면 훨씬 편해집니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Caps Lock &amp;rarr; Ctrl, 기존 Ctrl &amp;rarr; Esc: Vim, 터미널 사용할 때 손 이동이 크게 줄어듭니다.&lt;/li&gt;
&lt;li&gt;오른쪽 Command &amp;rarr; 한영 전환 키처럼 사용: macOS / Windows 모두 편하게 전환.&lt;/li&gt;
&lt;li&gt;Fn 조합으로 방향키 / Home / End / PageUp / PageDown을 한 손 안에 배치.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번 세팅해두면 키보드 내부에 저장되기 때문에, 다른 PC나 OS에 연결해도 같은 키맵을 그대로 사용할 수 있는 게 큰 장점입니다.&lt;/p&gt;
&lt;button class=&quot;hhkb_button&quot; type=&quot;button&quot;&gt; &lt;span class=&quot;hhkb_button-icon&quot;&gt;⬇&lt;/span&gt; HHKB 공식 사이트 / 키맵 툴 안내 &lt;/button&gt;&lt;/section&gt;
&lt;section id=&quot;hhkb_conclusion&quot; class=&quot;hhkb_animate&quot; data-hhkb-section=&quot;conclusion&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리 &amp;ndash; 이런 분들께 추천합니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 HHKB를 봤을 때 느낀 생각은 &amp;ldquo;너무 비싸고, 너무 특이하다&amp;rdquo;였습니다. 그런데 막상 써보니, &lt;b&gt;하루 종일 키보드를 두드리는 사람에게는 합리적인 투자&lt;/b&gt;일 수도 있겠다는 쪽에 가깝습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 아래와 같은 분들에게는 한 번쯤 진지하게 고려해볼 만한 키보드라고 생각합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코딩/터미널 작업 비중이 높아 Ctrl, Esc, 기호 키를 많이 쓰는 개발자&lt;/li&gt;
&lt;li&gt;책상 공간을 최대한 효율적으로 쓰고 싶은 분 (작은 사이즈, 깔끔한 레이아웃)&lt;/li&gt;
&lt;li&gt;기계식 키보드의 소음이 부담스럽지만, 키감은 포기하기 싫은 분&lt;/li&gt;
&lt;li&gt;Windows와 macOS를 오가며 작업하는 환경&lt;/li&gt;
&lt;li&gt;키보드를 &amp;ldquo;도구&amp;rdquo;이자 &amp;ldquo;취향&amp;rdquo;으로 즐기고 싶은 사람&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 HHKB는 절대 저렴한 키보드가 아닙니다. 하지만 하루 수천~수만 번 누르는 입력 장치라는 점, 그리고 손목과 손가락의 피로, 소음, 작업 효율까지 고려해보면 &amp;ldquo;나에게 맞는 키보드에 투자한다&amp;rdquo;는 관점에서 충분히 가치 있는 선택이 될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 HHKB Hybrid Professional Type-S를 고민하시는 분들께 실제 사용자의 경험과 설정 팁, 그리고 구매 판단에 도움이 되었기를 바랍니다.&lt;/p&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQafob/dJMcaboZqeA/d80FbSWHpSpjc7nfjjF7fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQafob/dJMcaboZqeA/d80FbSWHpSpjc7nfjjF7fk/img.png&quot; data-alt=&quot;키보드반품포장&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQafob/dJMcaboZqeA/d80FbSWHpSpjc7nfjjF7fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQafob%2FdJMcaboZqeA%2Fd80FbSWHpSpjc7nfjjF7fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키보드반품포장&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;첫 제품은 안타깝게도 불량으로 반품 포장을 했지만, 교환 후에는 만족스럽게 사용 중입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-block&quot;&gt;
&lt;div class=&quot;hhkb_image-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ac02a/dJMcaaRcqTo/DW7a1qVYXkBXNdF0QmbQn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ac02a/dJMcaaRcqTo/DW7a1qVYXkBXNdF0QmbQn1/img.png&quot; data-alt=&quot;제품온직후모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ac02a/dJMcaaRcqTo/DW7a1qVYXkBXNdF0QmbQn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAc02a%2FdJMcaaRcqTo%2FDW7a1qVYXkBXNdF0QmbQn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제품온직후모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;hhkb_image-caption&quot;&gt;지금은 이렇게 책상 위 한가운데에서, 하루 종일 코드를 받아내는 메인 키보드가 되었습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/main&gt;&lt;footer class=&quot;hhkb_tag-footer hhkb_animate&quot;&gt;
&lt;div class=&quot;hhkb_tag-list&quot;&gt;&lt;span class=&quot;hhkb_tag-chip&quot;&gt;#HHKB&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#해피해킹키보드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#개발자키보드추천&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#무접점키보드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#HybridTypeS&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#Topre&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#코딩키보드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#블루투스키보드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#유선무선하이브리드&lt;/span&gt; &lt;span class=&quot;hhkb_tag-chip&quot;&gt;#키보드리뷰&lt;/span&gt;&lt;/div&gt;
&lt;/footer&gt;&lt;/div&gt;
&lt;script&gt;
(function() {
  var hhkb_links = document.querySelectorAll('.hhkb_toc-link');
  hhkb_links.forEach(function(link) {
    link.addEventListener('click', function() {
      var targetId = link.getAttribute('data-hhkb-target');
      if (!targetId) return;
      var section = document.getElementById('hhkb_' + targetId);
      if (!section) return;
      var rect = section.getBoundingClientRect();
      var offsetTop = window.pageYOffset + rect.top - 70;
      window.scrollTo({
        top: offsetTop,
        behavior: 'smooth'
      });
    });
  });
})();
&lt;/script&gt;</description>
      <category>IT/Product</category>
      <category>HHKB</category>
      <category>hybrid</category>
      <category>topre</category>
      <category>type-s</category>
      <category>개발자키보드추천</category>
      <category>무접점키보드</category>
      <category>블루투스키보드</category>
      <category>유선무선하이브리드</category>
      <category>코딩키보드</category>
      <category>해피해킹키보드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/559</guid>
      <comments>https://odinbox.tistory.com/559#entry559comment</comments>
      <pubDate>Sat, 15 Nov 2025 11:15:15 +0900</pubDate>
    </item>
    <item>
      <title>갤럭시스마트태그2, 개봉기 및 사용후기</title>
      <link>https://odinbox.tistory.com/558</link>
      <description>&lt;section id=&quot;gst2x&quot; data-gst2=&quot;v1&quot;&gt;
&lt;div&gt;
&lt;style&gt;
  #gst2x{
    --gst2x-ink:#0f172a;--gst2x-muted:#5b6b86;--gst2x-bg:#fff;--gst2x-line:#e7eef7;
    --gst2x-brand:#1f49c9;--gst2x-accent:#67cfff;--gst2x-chip:#f1f6ff;--gst2x-ok:#2fb673;
    --gst2x-shadow:0 16px 40px rgba(5,25,78,.12);
    font-family:Pretendard,&quot;Noto Sans KR&quot;,ui-sans-serif,system-ui;color:var(--gst2x-ink);
    background:var(--gst2x-bg);max-width:980px;margin:0 auto;padding:0 16px 64px;line-height:1.78
  }
  #gst2x .gst2x-hero{
    position:relative;border-radius:22px;margin:18px 0 22px;overflow:hidden;box-shadow:var(--gst2x-shadow);
    background:linear-gradient(120deg,#0a1324,#0b172c,#0a1324);
    animation:gst2x-heroShift 12s ease-in-out infinite
  }
  @keyframes gst2x-heroShift{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}
  #gst2x .gst2x-hero-wrap{position:relative;z-index:1;padding:26px 22px 12px}
  #gst2x .gst2x-summary{color:#bcd7ff;font-size:.95rem;margin:0 0 6px 0;letter-spacing:.1px}
  #gst2x .gst2x-hero-title{margin:0;color:#f4f7ff;font-weight:800;letter-spacing:-.2px;line-height:1.24;font-size:clamp(1.8rem,3.6vw,2.5rem)}
  #gst2x .gst2x-sub{margin:8px 0 14px;color:#d7e6ff;font-size:clamp(.95rem,1.6vw,1.06rem)}
  #gst2x .gst2x-hero-thumb{padding:0 22px 22px}
  #gst2x .gst2x-toc{margin:16px 0 22px;background:#f8fbff;border:1px solid var(--gst2x-line);border-radius:18px;padding:14px 16px}
  #gst2x .gst2x-toc-title{display:block;margin-bottom:8px;color:#183a8a}
  #gst2x .gst2x-toc-list{margin:0;padding:0;display:grid;grid-template-columns:1fr;gap:6px}
  #gst2x .gst2x-toc-item{list-style:none;padding:10px 12px 10px 44px;border:1px solid #dbe9ff;background:#fff;border-radius:14px;position:relative}
  #gst2x .gst2x-toc-item::before{content:&quot;&quot;;position:absolute;left:12px;top:50%;transform:translateY(-50%);width:22px;height:22px;border-radius:999px;background:radial-gradient(circle at 30% 30%,#fff,#b7d7ff 60%,#6aa8ff 100%);box-shadow:0 6px 14px rgba(36,96,196,.28)}
  #gst2x .gst2x-toc-link{text-decoration:none;color:#0b3382}
  #gst2x .gst2x-toc-link:hover{text-decoration:underline}
  #gst2x h2{
    display:inline-block;margin:32px 0 12px;padding:8px 14px;border-radius:18px;
    background:linear-gradient(90deg,#e9f2ff,#f7fbff);
    box-shadow:inset 0 0 0 1px #d9e8ff,0 10px 20px rgba(18,52,128,.06);
    font-size:clamp(1.2rem,2.4vw,1.52rem);color:#0b2b86
  }
  #gst2x h3{margin:18px 0 8px;font-size:1.06rem;color:#18356c}
  #gst2x p{margin:10px 0}
  #gst2x .gst2x-hl{background:linear-gradient(120deg,rgba(31,73,201,.16),rgba(103,207,255,.16));padding:2px 6px;border-radius:6px}
  #gst2x .gst2x-grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
  @media(max-width:760px){#gst2x .gst2x-grid2{grid-template-columns:1fr}}
  #gst2x .gst2x-photo{border:1px dashed #cfe2ff;background:linear-gradient(180deg,#fbfdff,#f7fbff);color:var(--gst2x-muted);border-radius:16px;padding:12px;text-align:center;margin:16px 0;font-size:.95rem;box-shadow:0 6px 18px rgba(18,47,90,.05)}
  #gst2x .gst2x-photo img{max-width:100%;border-radius:12px;display:block;margin:6px auto 0}
  #gst2x .gst2x-spec{width:100%;border-collapse:collapse;margin:12px 0;font-size:.98rem}
  #gst2x .gst2x-spec th,#gst2x .gst2x-spec td{border:1px solid var(--gst2x-line);padding:10px 12px}
  #gst2x .gst2x-spec th{background:#f1f6ff;text-align:left;width:28%}
  #gst2x .gst2x-steps{display:grid;grid-template-columns:1fr;gap:10px;margin:10px 0}
  #gst2x .gst2x-step{border:1px solid #dce8ff;background:#fff;border-radius:14px;padding:12px 12px 12px 48px;position:relative}
  #gst2x .gst2x-mark{position:absolute;left:12px;top:12px;width:24px;height:24px;border-radius:999px;background:linear-gradient(135deg,#2b60ff,#67cfff);color:#fff;font-weight:700;font-size:.9rem;display:flex;align-items:center;justify-content:center;box-shadow:0 6px 14px rgba(30,80,190,.25)}
  #gst2x .gst2x-tip{background:#f7fbff;border:1px solid var(--gst2x-line);border-radius:14px;padding:12px;margin:12px 0}
  #gst2x .gst2x-kw-cloud{display:flex;flex-wrap:wrap;gap:12px;margin:14px 0 6px}
  #gst2x .gst2x-kw{display:inline-flex;align-items:center;justify-content:center;padding:10px 16px;border-radius:999px;user-select:none;pointer-events:none;color:#0e318a;font-weight:700;background:radial-gradient(60px 30px at 30% 30%,#fff,#d9ebff 60%,#b8d8ff 100%);box-shadow:0 10px 24px rgba(46,101,214,.18),inset 0 0 0 1px #cfe2ff;transition:transform .35s ease,box-shadow .35s ease,filter .35s ease}
  #gst2x .gst2x-kw:hover{transform:translateY(-5px) scale(1.05);box-shadow:0 18px 32px rgba(46,101,214,.25),inset 0 0 0 1px #b5d3ff;filter:saturate(1.08)}
  #gst2x .gst2x-checklist{display:grid;grid-template-columns:1fr;gap:10px;margin:12px 0}
  #gst2x .gst2x-check{position:relative;border:1px solid #dfe9ff;background:#fff;border-radius:14px;padding:12px 12px 12px 48px}
  #gst2x .gst2x-check::before{content:&quot;&quot;;position:absolute;left:12px;top:12px;width:24px;height:24px;border-radius:8px;background:conic-gradient(from 180deg,var(--gst2x-ok),#44d08c);box-shadow:inset 0 0 0 2px #eafff3}
  #gst2x .gst2x-check::after{content:&quot;&quot;;position:absolute;left:19px;top:18px;width:10px;height:6px;border-left:3px solid #fff;border-bottom:3px solid #fff;transform:rotate(-45deg)}
  #gst2x .gst2x-cta{background:linear-gradient(180deg,#fff,#f8fbff);border:1px solid var(--gst2x-line);border-radius:16px;padding:14px 16px;margin:20px 0}
  #gst2x a{color:#0b3382}
&lt;/style&gt;
&lt;/div&gt;
&lt;header class=&quot;gst2x-hero&quot;&gt;
&lt;div class=&quot;gst2x-hero-wrap&quot;&gt;
&lt;p class=&quot;gst2x-summary&quot; data-ke-size=&quot;size16&quot;&gt;분실과 도난을 예방하고 빠르게 찾아야 한다면 이 조합이 가장 간단합니다.&lt;/p&gt;
&lt;h1 class=&quot;gst2x-hero-title&quot;&gt;갤럭시 스마트태그2(EI_T6600) 개봉기 &amp;middot; 연결 방법 &amp;middot; 스펙/후기 총정리&lt;/h1&gt;
&lt;p class=&quot;gst2x-sub&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gst2x-hero-thumb&quot;&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRHB66/dJMb9YccfUs/YekGFlKeic0hJ5digTCBKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRHB66/dJMb9YccfUs/YekGFlKeic0hJ5digTCBKK/img.png&quot; data-alt=&quot;대표 썸네일 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRHB66/dJMb9YccfUs/YekGFlKeic0hJ5digTCBKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRHB66%2FdJMb9YccfUs%2FYekGFlKeic0hJ5digTCBKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (2).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;대표 썸네일 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/header&gt;&lt;nav class=&quot;gst2x-toc&quot; aria-label=&quot;목차&quot;&gt;&lt;b&gt;목차&lt;/b&gt;
&lt;ul class=&quot;gst2x-toc-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-intro&quot;&gt;구매 이유와 변화&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-unbox&quot;&gt;개봉기와 구성품&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-desc&quot;&gt;제품 설명&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-design&quot;&gt;디자인과 착용 예시&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-connect&quot;&gt;SmartThings 연결 방법&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-spec&quot;&gt;상세 스펙&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-tips&quot;&gt;실사용 팁&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-wrap&quot;&gt;총평과 체크리스트&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;gst2x-toc-item&quot;&gt;&lt;a class=&quot;gst2x-toc-link&quot; href=&quot;#gst2x-keywords&quot;&gt;본문 키워드&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;section id=&quot;gst2x-intro&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;구매 이유와 변화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;gst2x-hl&quot;&gt;Galaxy SmartTag2(EI_T6600)&lt;/span&gt;은 분실 우려가 있는 물건을 빠르게 찾기 위해 선택했습니다. 전작 대비 마감과 내구성이 개선되었고, IP67 방수/방진을 지원합니다. 교체형 CR2032 배터리를 사용하여 유지 비용이 낮습니다. &lt;span class=&quot;gst2x-hl&quot;&gt;SmartThings&lt;/span&gt;와의 결합으로 실내&amp;middot;실외 모두에서 위치 파악이 수월합니다. UWB를 지원하는 단말에서는 근거리 정밀 탐색 기능이 동작하여 실내 탐색 효율이 높습니다.&lt;/p&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_01.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJyQ5Z/dJMb9N9FMZ6/mh06F7STvbnSWqi3QLP4T0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJyQ5Z/dJMb9N9FMZ6/mh06F7STvbnSWqi3QLP4T0/img.jpg&quot; data-alt=&quot;스마트태그2 제품상자 뒷면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJyQ5Z/dJMb9N9FMZ6/mh06F7STvbnSWqi3QLP4T0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJyQ5Z%2FdJMb9N9FMZ6%2Fmh06F7STvbnSWqi3QLP4T0%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;901&quot; height=&quot;1600&quot; data-filename=&quot;smarttag2_branded_01.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스마트태그2 제품상자 뒷면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-unbox&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개봉기와 구성품&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포장은 재활용 종이 기반으로 간결하게 설계되었습니다. 기본 구성품은 본체, CR2032 배터리 1개, 간단 사용설명서&amp;middot;보증 안내입니다.&lt;/p&gt;
&lt;div class=&quot;gst2x-grid2&quot;&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_02.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HTaHy/dJMb9NaK4K7/wYPQaO1y1fFQdF3cBX9fFk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HTaHy/dJMb9NaK4K7/wYPQaO1y1fFQdF3cBX9fFk/img.jpg&quot; data-alt=&quot;스마트태그2 구성품&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HTaHy/dJMb9NaK4K7/wYPQaO1y1fFQdF3cBX9fFk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHTaHy%2FdJMb9NaK4K7%2FwYPQaO1y1fFQdF3cBX9fFk%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;901&quot; height=&quot;1600&quot; data-filename=&quot;smarttag2_branded_02.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스마트태그2 구성품&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_08.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buZmgh/dJMb9PGp29f/dojLgDvDyThmv3nIyf8QT1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buZmgh/dJMb9PGp29f/dojLgDvDyThmv3nIyf8QT1/img.jpg&quot; data-alt=&quot;스마트태그2 제품상자 뒷면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buZmgh/dJMb9PGp29f/dojLgDvDyThmv3nIyf8QT1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuZmgh%2FdJMb9PGp29f%2FdojLgDvDyThmv3nIyf8QT1%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;901&quot; height=&quot;1600&quot; data-filename=&quot;smarttag2_branded_08.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스마트태그2 제품상자 뒷면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-desc&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;제품 설명&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EI_T6600은 블루투스 저전력 통신을 기반으로 위치 정보를 공유합니다. 사용자는 SmartThings 앱에서 장치를 등록하고, 지도를 통해 현재 또는 마지막 확인 위치를 파악할 수 있습니다. 분실 모드에서는 주변의 갤럭시 기기가 태그 신호를 익명으로 감지하여 소유자에게 위치 정보를 전달합니다. 버튼 입력은 단일&amp;middot;길게 누르기 동작을 인식하며, 조명이나 에어컨 같은 스마트홈 장치 제어에 연결할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본체는 작고 가벼운 고리형 구조로 키링, 가방, 애견 목줄 등 다양한 장착 위치에 어울립니다. 생활 스크래치와 오염에 강한 표면 처리로 관리가 쉽습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-design&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;디자인과 착용 예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매끈한 고리형 외형은 시각적으로 단정하며 장착 편의성이 우수합니다. 가방 지퍼 손잡이나 열쇠고리에 연결해도 이질감이 적습니다.&lt;/p&gt;
&lt;div class=&quot;gst2x-grid2&quot;&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_03.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4MC4i/dJMb9MiCYnQ/BnjnkPR2FEP3FuUFsSuXI0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4MC4i/dJMb9MiCYnQ/BnjnkPR2FEP3FuUFsSuXI0/img.jpg&quot; data-alt=&quot;스마트태그2 앞면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4MC4i/dJMb9MiCYnQ/BnjnkPR2FEP3FuUFsSuXI0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4MC4i%2FdJMb9MiCYnQ%2FBnjnkPR2FEP3FuUFsSuXI0%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;901&quot; height=&quot;1600&quot; data-filename=&quot;smarttag2_branded_03.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스마트태그2 앞면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_04.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oYA6a/dJMb9OU2xvF/S5tOLouYBRKVy1ABVWqa1k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oYA6a/dJMb9OU2xvF/S5tOLouYBRKVy1ABVWqa1k/img.jpg&quot; data-alt=&quot;스마트태그2 후면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oYA6a/dJMb9OU2xvF/S5tOLouYBRKVy1ABVWqa1k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoYA6a%2FdJMb9OU2xvF%2FS5tOLouYBRKVy1ABVWqa1k%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;901&quot; height=&quot;1600&quot; data-filename=&quot;smarttag2_branded_04.jpg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스마트태그2 후면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-connect&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SmartThings 연결 방법&lt;/h2&gt;
&lt;div class=&quot;gst2x-steps&quot;&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;1&lt;/div&gt;
&lt;b&gt;준비&lt;/b&gt; 블루투스를 켠 갤럭시 스마트폰과 최신 SmartThings 앱을 준비합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;2&lt;/div&gt;
&lt;b&gt;배터리 장착&lt;/b&gt; 커버를 열고 CR2032를 +면이 위로 오게 넣습니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;3&lt;/div&gt;
&lt;b&gt;페어링&lt;/b&gt; 측면 버튼을 길게 눌러 동작음을 확인합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;4&lt;/div&gt;
&lt;b&gt;앱에서 추가&lt;/b&gt; SmartThings &amp;rarr; 디바이스 &amp;rarr; + &amp;rarr; 디바이스 추가 &amp;rarr; 주변 검색에서 SmartTag2를 선택합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;5&lt;/div&gt;
&lt;b&gt;권한 허용&lt;/b&gt; 블루투스&amp;middot;위치&amp;middot;인근 기기 권한을 허용합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;6&lt;/div&gt;
&lt;b&gt;이름과 아이콘&lt;/b&gt; 열쇠, 백팩 등 구분하기 쉬운 이름과 아이콘을 선택합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;7&lt;/div&gt;
&lt;b&gt;네트워크 참여&lt;/b&gt; SmartThings Find 네트워크 참여를 켭니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;8&lt;/div&gt;
&lt;b&gt;정밀 탐색&lt;/b&gt; UWB 지원 단말이라면 근거리 정밀 탐색을 활성화합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-step&quot;&gt;
&lt;div class=&quot;gst2x-mark&quot;&gt;9&lt;/div&gt;
&lt;b&gt;동작 확인&lt;/b&gt; 벨 울리기와 지도 위치가 정상인지 확인합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gst2x-tip&quot;&gt;&lt;b&gt;문제 해결&lt;/b&gt; 연결 항목이 보이지 않으면 블루투스를 재시작하고, 태그 버튼을 길게 눌러 페어링을 다시 시도합니다. 그래도 실패하면 앱 캐시를 삭제한 뒤 재검색합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-grid2&quot;&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_05.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZfcWL/dJMb9MiCYnP/PobwnUyAZMuUvy3IlZvXk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZfcWL/dJMb9MiCYnP/PobwnUyAZMuUvy3IlZvXk1/img.jpg&quot; data-alt=&quot;갤럭시 태그 찾기 &amp;amp;middot; 설정과정 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZfcWL/dJMb9MiCYnP/PobwnUyAZMuUvy3IlZvXk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZfcWL%2FdJMb9MiCYnP%2FPobwnUyAZMuUvy3IlZvXk1%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;720&quot; height=&quot;1414&quot; data-filename=&quot;smarttag2_branded_05.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;갤럭시 태그 찾기 &amp;middot; 설정과정 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_06.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wXpzo/dJMb9Ywu4nx/E4xVNYDSYObaksqOIhwHm0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wXpzo/dJMb9Ywu4nx/E4xVNYDSYObaksqOIhwHm0/img.jpg&quot; data-alt=&quot;갤럭시 태그 찾기 &amp;amp;middot; 설정과정 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wXpzo/dJMb9Ywu4nx/E4xVNYDSYObaksqOIhwHm0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwXpzo%2FdJMb9Ywu4nx%2FE4xVNYDSYObaksqOIhwHm0%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;720&quot; height=&quot;1414&quot; data-filename=&quot;smarttag2_branded_06.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;갤럭시 태그 찾기 &amp;middot; 설정과정 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gst2x-photo&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;smarttag2_branded_07.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpImqH/dJMb9MbQA0W/JpsZ9FGfUmPM75K3sHIHe0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpImqH/dJMb9MbQA0W/JpsZ9FGfUmPM75K3sHIHe0/img.jpg&quot; data-alt=&quot;갤럭시 태그 찾기 &amp;amp;middot; 설정과정 3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpImqH/dJMb9MbQA0W/JpsZ9FGfUmPM75K3sHIHe0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpImqH%2FdJMb9MbQA0W%2FJpsZ9FGfUmPM75K3sHIHe0%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;720&quot; height=&quot;1414&quot; data-filename=&quot;smarttag2_branded_07.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;갤럭시 태그 찾기 &amp;middot; 설정과정 3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-spec&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상세 스펙&lt;/h2&gt;
&lt;table class=&quot;gst2x-spec&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;모델&lt;/th&gt;
&lt;td&gt;Galaxy SmartTag2 (EI_T6600)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;무선&lt;/th&gt;
&lt;td&gt;Bluetooth Low Energy, UWB 정밀 탐색(지원 단말 한정)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;방수/방진&lt;/th&gt;
&lt;td&gt;IP67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;배터리&lt;/th&gt;
&lt;td&gt;CR2032 교체형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;알림&lt;/th&gt;
&lt;td&gt;벨 울리기, 마지막 위치 기록, 근접 알림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;네트워크&lt;/th&gt;
&lt;td&gt;SmartThings Find 익명 크라우드 감지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;자동화&lt;/th&gt;
&lt;td&gt;버튼 액션으로 스마트홈 장치 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;호환&lt;/th&gt;
&lt;td&gt;갤럭시 스마트폰 + SmartThings 앱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;크기/무게&lt;/th&gt;
&lt;td&gt;소형 경량 고리형(휴대와 장착 용이)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;사용 환경&lt;/th&gt;
&lt;td&gt;실내&amp;middot;실외, 일반 생활 방수 조건&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p class=&quot;gst2x-cta&quot; data-ke-size=&quot;size16&quot;&gt;배터리 수명과 정밀 탐색 성능은 스마트폰 모델, 펌웨어, 온도, 사용 패턴에 따라 달라질 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-tips&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실사용 팁&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;분실 모드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SmartThings에서 디바이스를 선택하여 분실 모드를 켭니다. 연락처 메시지를 저장하면 발견자가 휴대폰으로 확인할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정밀 탐색&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UWB 지원 단말에서는 화살표 안내로 근거리 탐색이 수월합니다. 실내 환경에서 효과가 큽니다.&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;/section&gt;
&lt;section id=&quot;gst2x-wrap&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;총평과 체크리스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EI_T6600은 갤럭시 사용자에게 실질적인 가치를 주는 분실 방지 액세서리입니다. 실내와 실외 모두에서 위치 파악이 빠르며, IP67과 교체형 배터리로 관리가 쉽습니다. iOS 중심 환경에서는 활용에 제약이 있으므로 갤럭시 생태계에서 사용할 때 만족도가 높습니다.&lt;/p&gt;
&lt;div class=&quot;gst2x-checklist&quot;&gt;
&lt;div class=&quot;gst2x-check&quot;&gt;갤럭시 스마트폰을 사용합니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-check&quot;&gt;항상 들고 다니는 물건이 있습니다.&lt;/div&gt;
&lt;div class=&quot;gst2x-check&quot;&gt;스마트홈 자동화를 활용하고 싶습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;gst2x-keywords&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;본문 키워드&lt;/h2&gt;
&lt;div class=&quot;gst2x-kw-cloud&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;gst2x-kw&quot;&gt;갤럭시태그2&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;Galaxy SmartTag2&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;EI_T6600&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;스마트싱스&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;SmartThings Find&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;UWB 정밀탐색&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;IP67&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;블루투스 태그&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;분실 모드&lt;/span&gt; &lt;span class=&quot;gst2x-kw&quot;&gt;벨 울리기&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;color: var(--gst2x-muted); margin-top: 6px;&quot; data-ke-size=&quot;size16&quot;&gt;키워드는 시각 효과만 제공하며 클릭 기능은 제공하지 않습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;</description>
      <category>IT</category>
      <category>EI_T6600</category>
      <category>GalaxySmartTag2</category>
      <category>IP67</category>
      <category>SmartThings Find</category>
      <category>UWB</category>
      <category>갤럭시태그2</category>
      <category>분실방지</category>
      <category>블루투스태그</category>
      <category>스마트싱스</category>
      <category>위치추적기</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/558</guid>
      <comments>https://odinbox.tistory.com/558#entry558comment</comments>
      <pubDate>Sat, 8 Nov 2025 09:35:15 +0900</pubDate>
    </item>
    <item>
      <title>자동차 하체 수리 가이드</title>
      <link>https://odinbox.tistory.com/557</link>
      <description>&lt;section id=&quot;lfunderprice_article&quot;&gt;
&lt;div&gt;
&lt;style&gt;
    #lfunderprice_article{
      --hyundai-blue:#002c5f;
      --hyundai-sand:#e4cdc3;
      --hyundai-light-sand:#f6f3f2;
      --hyundai-gold:#a36b4f;
      --active-blue:#00aad2;
      --sky-blue:#aacae6;
      --active-red:#e63312;
      --ink:#0f172a;
      --muted:#5b6b86;
      --line:#e7eef7;
      --brand:var(--hyundai-blue);
      --accent:var(--active-blue);
      --bg:#ffffff;
      --shadow:0 10px 30px rgba(3,22,61,.06);
      --r:18px;
      font-family:Pretendard,&quot;Noto Sans KR&quot;,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,&quot;Apple SD Gothic Neo&quot;,&quot;Malgun Gothic&quot;,sans-serif;
      color:var(--ink)
    }
    .lfunderprice_wrap{max-width:1000px;margin:0 auto;padding:28px 18px}
    .lfunderprice_title{font-size:clamp(24px,3.4vw,36px);font-weight:900;letter-spacing:-.01em;margin:0 0 8px}
    .lfunderprice_sub{color:var(--muted);font-size:14px;margin-bottom:16px}
    .lfunderprice_thumb{border:1px solid var(--line);border-radius:16px;background:#fff;box-shadow:var(--shadow);overflow:hidden;margin-bottom:18px}
    .lfunderprice_thumbcap{padding:10px 12px;background:linear-gradient(90deg,var(--hyundai-light-sand),#fff)}
    .lfunderprice_thumbcap b{color:var(--brand)}
    .lfunderprice_hero{border:1px solid var(--line);background:linear-gradient(160deg,#f7fbff 0%,#ffffff 100%);border-radius:20px;padding:clamp(16px,2.4vw,24px);box-shadow:var(--shadow);margin-bottom:24px}

    .lfunderprice_sec{margin:26px 0 18px}
    .lfunderprice_head{display:flex;align-items:center;gap:12px}
    .lfunderprice_titlebar{position:relative;display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:14px;border:1px solid var(--line);background:#fff;box-shadow:var(--shadow)}
    .lfunderprice_num{width:32px;height:32px;border-radius:10px;background:linear-gradient(135deg,var(--brand),var(--accent));color:#fff;display:flex;align-items:center;justify-content:center;font-weight:900}
    .lfunderprice_h2{font-size:clamp(18px,2.4vw,22px);font-weight:900;margin:0}
    .lfunderprice_titlebar:after{content:&quot;&quot;;position:absolute;left:14px;right:14px;bottom:-6px;height:6px;border-radius:0 0 10px 10px;background:linear-gradient(90deg,rgba(0,44,95,.18),rgba(0,170,210,.18))}
    .lfunderprice_h3{font-size:clamp(15px,2.2vw,18px);font-weight:800;margin:14px 0 8px}
    .lfunderprice_p{line-height:1.72;margin:8px 0 12px}

    .lfunderprice_gallery{display:grid;gap:14px;grid-template-columns:repeat(12,1fr)}
    .lfunderprice_fig{grid-column:span 12;border:1px solid var(--line);border-radius:16px;background:#fff;box-shadow:var(--shadow);overflow:hidden;transition:transform .2s}
    .lfunderprice_fig:hover{transform:translateY(-2px)}
    .lfunderprice_figcap{padding:10px 12px}
    .lfunderprice_figcap h4{margin:0 0 6px 0;font-weight:800}
    .lfunderprice_figcap p{margin:0;color:var(--muted);font-size:13px}
    @media(min-width:860px){.lfunderprice_fig.col-6{grid-column:span 6}.lfunderprice_fig.col-12{grid-column:span 12}}

    .lfunderprice_cards{display:grid;gap:12px;grid-template-columns:repeat(12,1fr)}
    .lfunderprice_card{grid-column:span 12;border:1px solid var(--line);border-radius:16px;padding:14px;background:#fff;box-shadow:var(--shadow);opacity:0;animation:lfunderprice_fade .55s ease forwards}
    @media(min-width:760px){.lfunderprice_card.sm-6{grid-column:span 6}.lfunderprice_card.sm-4{grid-column:span 4}}
    @keyframes lfunderprice_fade{from{transform:translateY(8px);opacity:0}to{transform:translateY(0);opacity:1}}

    .lfunderprice_list{list-style:none;padding:0;margin:8px 0}
    .lfunderprice_list li{position:relative;padding-left:16px;margin:8px 0}
    .lfunderprice_list li::before{content:&quot;&quot;;position:absolute;left:0;top:.68em;width:8px;height:8px;border-radius:50%;background:linear-gradient(135deg,var(--brand),var(--accent))}

    .lfunderprice_table_wrap{overflow-x:auto;border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow)}
    .lfunderprice_table{width:100%;border-collapse:collapse;min-width:900px}
    .lfunderprice_table th,.lfunderprice_table td{padding:12px 14px;border-bottom:1px solid var(--line);text-align:left}
    .lfunderprice_table thead th{position:sticky;top:0;background:#f3f7ff;font-weight:800}
    .lfunderprice_table tr:hover td{background:#fafcff}

    .lfunderprice_flag{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px}
    .lfunderprice_flag.bad{background:rgba(230,51,18,.12);color:#7a1b1b;border:1px solid rgba(230,51,18,.25)}
    .lfunderprice_flag.warn{background:rgba(163,107,79,.12);color:#6b3d2a;border:1px solid rgba(163,107,79,.25)}
    .lfunderprice_flag.ok{background:rgba(18,184,134,.12);color:#0c6b57;border:1px solid rgba(18,184,134,.25)}

    .lfunderprice_links{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px}
    .lfunderprice_link{display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border-radius:12px;border:1px solid var(--line);text-decoration:none;color:var(--ink);background:#fff;box-shadow:var(--shadow);transition:transform .15s,box-shadow .15s}
    .lfunderprice_link:hover{transform:translateY(-2px);box-shadow:0 14px 28px rgba(0,0,0,.08)}

    .lfunderprice_note{border:1px dashed var(--line);background:#fbfdff;border-radius:12px;padding:10px 12px;color:var(--muted);font-size:13px}

    .lfunderprice_modal_mask{position:fixed;inset:0;background:rgba(10,22,40,.45);display:none;z-index:9998}
    .lfunderprice_modal{position:fixed;inset:0;display:none;align-items:center;justify-content:center;z-index:9999}
    .lfunderprice_modal_panel{width:min(980px,94vw);max-height:88vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid var(--line);box-shadow:0 24px 60px rgba(0,0,0,.18);animation:lfunderprice_zoom .18s ease}
    @keyframes lfunderprice_zoom{from{transform:scale(.98);opacity:0}to{transform:scale(1);opacity:1}}
    .lfunderprice_modal_hd{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--line);background:linear-gradient(90deg,var(--sky-blue),#ffffff)}
    .lfunderprice_modal_tit{font-weight:800}
    .lfunderprice_x{background:#fff;border:1px solid var(--line);border-radius:10px;padding:8px 12px;cursor:pointer}
    .lfunderprice_modal_bd{padding:16px 18px}
    .lfunderprice_grid2{display:grid;gap:12px;grid-template-columns:1fr}
    @media(min-width:880px){.lfunderprice_grid2{grid-template-columns:1.1fr .9fr}}
    .lfunderprice_sectionbox{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:#fff}
    .lfunderprice_table_small{width:100%;border-collapse:collapse}
    .lfunderprice_table_small th,.lfunderprice_table_small td{border-bottom:1px solid var(--line);padding:8px 10px;font-size:13px;text-align:left}
    .lfunderprice_kw{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
    .lfunderprice_kw span{border:1px dashed var(--line);padding:6px 10px;border-radius:999px;font-size:12px;background:#fcfdff}
  &lt;/style&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_wrap&quot;&gt;
&lt;p class=&quot;lfunderprice_sub&quot; data-ke-size=&quot;size16&quot;&gt;하체 소리에 따라 어떤 부품이 고장인지 그리고, 대략적인 정비비용에 대해서 알 수 있어요!&lt;/p&gt;
&lt;figure class=&quot;lfunderprice_thumb&quot; role=&quot;group&quot; aria-label=&quot;현대 컬러 팔레트 썸네일&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSK9Y0/dJMb9VT4EoG/k8wPEQ6y4kBOk699cPVnak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSK9Y0/dJMb9VT4EoG/k8wPEQ6y4kBOk699cPVnak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSK9Y0/dJMb9VT4EoG/k8wPEQ6y4kBOk699cPVnak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSK9Y0%2FdJMb9VT4EoG%2Fk8wPEQ6y4kBOk699cPVnak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;figcaption class=&quot;lfunderprice_thumbcap&quot; style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;b&gt;자동차 하체에 대해서 알아보도록 하겠습니다.&lt;/b&gt;
&lt;section class=&quot;lfunderprice_hero&quot;&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;LF소나타(2014~2019)의 하체 소음은 드라이브샤프트, 로워암, 스태빌라이저 링크, 타이로드엔드에서 주로 발생합니다. 먼저 사진으로 구조와 위치를 파악하고, 이어지는 표와 매뉴얼로 증상&amp;rarr;점검&amp;rarr;교체 순서대로 확인하세요.&lt;/p&gt;
&lt;/section&gt;
&lt;div id=&quot;sec-gallery&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;01&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;부품 구조&amp;middot;위치 갤러리&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_gallery&quot; aria-label=&quot;부품 사진 4장&quot;&gt;
&lt;figure class=&quot;lfunderprice_fig col-12&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mtjvI/dJMb9PGpFSW/nEnlX9KlAYGHAihjo5ESY1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mtjvI/dJMb9PGpFSW/nEnlX9KlAYGHAihjo5ESY1/img.jpg&quot; data-alt=&quot;드라이브샤프트 구조 (c) 강주원 자동차 홈&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mtjvI/dJMb9PGpFSW/nEnlX9KlAYGHAihjo5ESY1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmtjvI%2FdJMb9PGpFSW%2FnEnlX9KlAYGHAihjo5ESY1%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;684&quot; height=&quot;217&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;드라이브샤프트 구조 (c) 강주원 자동차 홈&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;figcaption class=&quot;lfunderprice_figcap&quot; style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;드라이브샤프트&lt;/h4&gt;
&lt;figure class=&quot;lfunderprice_fig col-12&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저속 코너 딱딱 소리와 가속 진동이 대표 신호입니다. 부츠만 손상이면 부츠 교체, 조인트 마모가 진행됐으면 재생 또는 신품 어셈블리를 고려합니다.&lt;/p&gt;
&lt;/figure&gt;
&lt;figure class=&quot;lfunderprice_fig col-6&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nYNMG/dJMb9OncfUS/E0wTyGfKi68wQZqkJkfOiK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nYNMG/dJMb9OncfUS/E0wTyGfKi68wQZqkJkfOiK/img.jpg&quot; data-alt=&quot;로워암 (c) 인터넷 사진 [부품]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nYNMG/dJMb9OncfUS/E0wTyGfKi68wQZqkJkfOiK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnYNMG%2FdJMb9OncfUS%2FE0wTyGfKi68wQZqkJkfOiK%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;644&quot; height=&quot;483&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로워암 (c) 인터넷 사진 [부품]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;figcaption class=&quot;lfunderprice_figcap&quot; style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로워암&lt;/h4&gt;
&lt;figure class=&quot;lfunderprice_fig col-6&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제동 시 앞머리가 꿀렁거리거나 직진성이 떨어지면 의심합니다. 부싱 균열과 볼조인트 유격, 부츠 손상을 확인하고 좌우 세트 교체 후 얼라이먼트를 진행합니다.&lt;/p&gt;
&lt;/figure&gt;
&lt;figure class=&quot;lfunderprice_fig col-6&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjFp4j/dJMb9OAJi69/bpkc8tIwBycBDqZKhY2kLk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjFp4j/dJMb9OAJi69/bpkc8tIwBycBDqZKhY2kLk/img.jpg&quot; data-alt=&quot;스태빌라이저 (c) 인터넷 사진 [부품]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjFp4j/dJMb9OAJi69/bpkc8tIwBycBDqZKhY2kLk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjFp4j%2FdJMb9OAJi69%2Fbpkc8tIwBycBDqZKhY2kLk%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;1000&quot; height=&quot;750&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스태빌라이저 (c) 인터넷 사진 [부품]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;figcaption class=&quot;lfunderprice_figcap&quot; style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스태빌라이저 링크&lt;/h4&gt;
&lt;figure class=&quot;lfunderprice_fig col-6&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방지턱&amp;middot;요철에서 딱딱&amp;middot;덜컹 소리가 나면 우선 확인합니다. 링크 볼조인트 부츠 손상과 유격이 핵심이며, 타이로드엔드와 같은 날 작업하면 공임을 줄일 수 있습니다.&lt;/p&gt;
&lt;/figure&gt;
&lt;figure class=&quot;lfunderprice_fig col-12&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSzhLp/dJMb9fdXbp7/Ij9ytyTK23tyaWptSJDJmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSzhLp/dJMb9fdXbp7/Ij9ytyTK23tyaWptSJDJmK/img.png&quot; data-alt=&quot;타이로드엔드 (c) 인터넷 사진&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSzhLp/dJMb9fdXbp7/Ij9ytyTK23tyaWptSJDJmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSzhLp%2FdJMb9fdXbp7%2FIj9ytyTK23tyaWptSJDJmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;272&quot; height=&quot;139&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;타이로드엔드 (c) 인터넷 사진&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;figcaption class=&quot;lfunderprice_figcap&quot; style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;타이로드엔드&lt;/h4&gt;
&lt;figure class=&quot;lfunderprice_fig col-12&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핸들 유격과 딱딱 소리, 복원력 저하가 나타납니다. 교체 후 토(Toe) 재설정이 중요합니다.&lt;/p&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;sec-parts-manual&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;02&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;부품별 전문 매뉴얼&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_cards&quot;&gt;
&lt;article class=&quot;lfunderprice_card sm-6&quot;&gt;
&lt;h3 class=&quot;lfunderprice_h3&quot; data-ke-size=&quot;size23&quot;&gt;드라이브샤프트&lt;/h3&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag bad&quot;&gt;증상&lt;/span&gt; 저속 코너 딱딱 소리, 가속 진동, 부츠 찢김과 그리스 비산&lt;/p&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag warn&quot;&gt;점검&lt;/span&gt; 내&amp;middot;외측 부츠 균열/누유, 조인트 유격 및 소리&lt;/p&gt;
&lt;ul class=&quot;lfunderprice_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부품가(개당) 180,000원~400,000원&lt;/li&gt;
&lt;li&gt;공임(개당) 70,000원~120,000원&lt;/li&gt;
&lt;li&gt;대안: 부츠 교체 60,000원~120,000원&lt;/li&gt;
&lt;li&gt;예시 번호 LH 49500-L1400, RH 49501-L0010&lt;/li&gt;
&lt;/ul&gt;
&lt;/article&gt;
&lt;article class=&quot;lfunderprice_card sm-6&quot;&gt;
&lt;h3 class=&quot;lfunderprice_h3&quot; data-ke-size=&quot;size23&quot;&gt;로워암&lt;/h3&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag bad&quot;&gt;증상&lt;/span&gt; 제동 시 앞머리 꿀렁, 덜컹, 직진 불안, 타이어 편마모&lt;/p&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag warn&quot;&gt;점검&lt;/span&gt; 부싱 균열, 볼조인트 유격, 부츠 손상&lt;/p&gt;
&lt;ul class=&quot;lfunderprice_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부품가(개당) 120,000원~260,000원&lt;/li&gt;
&lt;li&gt;공임(개당) 50,000원~90,000원&lt;/li&gt;
&lt;li&gt;예시 번호 RH 54501-C1000, LH 54500-C1000&lt;/li&gt;
&lt;/ul&gt;
&lt;/article&gt;
&lt;article class=&quot;lfunderprice_card sm-6&quot;&gt;
&lt;h3 class=&quot;lfunderprice_h3&quot; data-ke-size=&quot;size23&quot;&gt;스태빌라이저 링크&lt;/h3&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag bad&quot;&gt;증상&lt;/span&gt; 요철 통과 시 딱딱&amp;middot;덜컹, 롤 억제력 저하&lt;/p&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag warn&quot;&gt;점검&lt;/span&gt; 링크 볼조인트 부츠 손상과 유격, 타격음&lt;/p&gt;
&lt;ul class=&quot;lfunderprice_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부품가(개당) 30,000원~80,000원&lt;/li&gt;
&lt;li&gt;공임(개당) 20,000원~40,000원&lt;/li&gt;
&lt;li&gt;예시 번호 54840-E6000(RH)&lt;/li&gt;
&lt;/ul&gt;
&lt;/article&gt;
&lt;article class=&quot;lfunderprice_card sm-6&quot;&gt;
&lt;h3 class=&quot;lfunderprice_h3&quot; data-ke-size=&quot;size23&quot;&gt;타이로드엔드&lt;/h3&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag bad&quot;&gt;증상&lt;/span&gt; 핸들 유격과 딱딱 소리, 복원력 저하, 고속 떨림&lt;/p&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;lfunderprice_flag warn&quot;&gt;점검&lt;/span&gt; 조향 링크 유격, 부츠 손상&lt;/p&gt;
&lt;ul class=&quot;lfunderprice_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부품가(개당) 30,000원~80,000원&lt;/li&gt;
&lt;li&gt;공임(개당) 20,000원~40,000원&lt;/li&gt;
&lt;li&gt;예시 번호 RH 56825-C1090, LH 56820-C1000, 56820-L1000&lt;/li&gt;
&lt;/ul&gt;
&lt;/article&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_note&quot;&gt;부품번호는 연식&amp;middot;트림&amp;middot;엔진&amp;middot;옵션에 따라 달라질 수 있습니다. 정비 전 VIN 또는 차대번호으로 최종 확인하세요.&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;sec-parts-choice&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;03&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;부품 선택 기준(순정&amp;middot;재생&amp;middot;대체)&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_table_wrap&quot;&gt;
&lt;table class=&quot;lfunderprice_table&quot; aria-label=&quot;부품 선택 가이드&quot; 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;주의&lt;/th&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;순정(블루핸즈&amp;middot;오토큐)&lt;/td&gt;
&lt;td&gt;호환성&amp;middot;품질 안정, 정비 이력&amp;middot;보증 처리 용이&lt;/td&gt;
&lt;td&gt;가격 상단&lt;/td&gt;
&lt;td&gt;상&lt;/td&gt;
&lt;td&gt;소음&amp;middot;진동 민감, 장기 보유&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;대체(OEM&amp;middot;애프터마켓)&lt;/td&gt;
&lt;td&gt;가성비, 브랜드 선택 폭&lt;/td&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;품질&amp;middot;보증 편차, 코어 반납&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;/div&gt;
&lt;div id=&quot;sec-vin&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;04&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;VIN으로 내 차 부품번호 정확히 찾기&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_cards&quot;&gt;
&lt;div class=&quot;lfunderprice_card&quot;&gt;
&lt;div class=&quot;lfunderprice_h3&quot;&gt;5단계 매뉴얼&lt;/div&gt;
&lt;ul class=&quot;lfunderprice_list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;차량번호&amp;middot;VIN 확보: 등록증, 전면 유리 하단, 운전석 하단 플레이트 확인&lt;/li&gt;
&lt;li&gt;공식 EPC 조회: 블루핸즈&amp;middot;오토큐에 VIN 전달 후 부품번호 확인&lt;/li&gt;
&lt;li&gt;리비전 확인: 개선품&amp;middot;연식 변경 여부 점검&lt;/li&gt;
&lt;li&gt;호환 대조: 대체&amp;middot;재생 사용 시 OE 번호 일치, 보증 조건 확인&lt;/li&gt;
&lt;li&gt;작업 전 대조: 실제 박스 번호와 EPC 번호 일치, RH/LH 표기 확인&lt;/li&gt;
&lt;li&gt;* 차대번호로 조회 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;sec-hk-cost&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;05&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;현대&amp;middot;기아 인기 차종 비용 범위&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_table_wrap&quot;&gt;
&lt;table class=&quot;lfunderprice_table&quot; aria-label=&quot;현대&amp;middot;기아 인기 차종 하체 비용(참고)&quot; 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;로워암(좌우)&lt;/th&gt;
&lt;th&gt;드라이브샤프트(좌우)&lt;/th&gt;
&lt;th&gt;타이로드엔드(좌우)&lt;/th&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;아반떼 CN7&lt;/td&gt;
&lt;td&gt;90,000원~160,000원&lt;/td&gt;
&lt;td&gt;260,000원~400,000원&lt;/td&gt;
&lt;td&gt;360,000원~560,000원&lt;/td&gt;
&lt;td&gt;80,000원~130,000원&lt;/td&gt;
&lt;td&gt;90,000원~120,000원&lt;/td&gt;
&lt;td&gt;준중형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;쏘나타 LF/DN8&lt;/td&gt;
&lt;td&gt;120,000원~200,000원&lt;/td&gt;
&lt;td&gt;350,000원~500,000원&lt;/td&gt;
&lt;td&gt;450,000원~700,000원&lt;/td&gt;
&lt;td&gt;100,000원~160,000원&lt;/td&gt;
&lt;td&gt;100,000원~150,000원&lt;/td&gt;
&lt;td&gt;중형 기준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;그랜저 IG/GN7&lt;/td&gt;
&lt;td&gt;140,000원~220,000원&lt;/td&gt;
&lt;td&gt;420,000원~620,000원&lt;/td&gt;
&lt;td&gt;520,000원~780,000원&lt;/td&gt;
&lt;td&gt;110,000원~170,000원&lt;/td&gt;
&lt;td&gt;110,000원~160,000원&lt;/td&gt;
&lt;td&gt;대형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;스포티지 NQ5&lt;/td&gt;
&lt;td&gt;130,000원~210,000원&lt;/td&gt;
&lt;td&gt;380,000원~560,000원&lt;/td&gt;
&lt;td&gt;520,000원~780,000원&lt;/td&gt;
&lt;td&gt;110,000원~170,000원&lt;/td&gt;
&lt;td&gt;110,000원~160,000원&lt;/td&gt;
&lt;td&gt;SUV 2WD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;쏘렌토 MQ4(4WD)&lt;/td&gt;
&lt;td&gt;140,000원~230,000원&lt;/td&gt;
&lt;td&gt;420,000원~620,000원&lt;/td&gt;
&lt;td&gt;560,000원~840,000원&lt;/td&gt;
&lt;td&gt;120,000원~180,000원&lt;/td&gt;
&lt;td&gt;120,000원~170,000원&lt;/td&gt;
&lt;td&gt;SUV 4WD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_note&quot;&gt;표는 평균 범위이며 지역 공임&amp;middot;부품 브랜드&amp;middot;사양에 따라 달라질 수 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;sec-shop-cost&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;06&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;정비소 유형별 비용 가이드&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_table_wrap&quot;&gt;
&lt;table class=&quot;lfunderprice_table&quot; aria-label=&quot;정비소 유형별 하체 비용 비교&quot; 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;링크(좌우)&lt;/th&gt;
&lt;th&gt;로워암(좌우)&lt;/th&gt;
&lt;th&gt;드라이브샤프트(좌우)&lt;/th&gt;
&lt;th&gt;타이로드엔드(좌우)&lt;/th&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;현대 블루핸즈&lt;/td&gt;
&lt;td&gt;순정부품, 기록&amp;middot;AS 용이&lt;/td&gt;
&lt;td&gt;120,000원~200,000원&lt;/td&gt;
&lt;td&gt;350,000원~500,000원&lt;/td&gt;
&lt;td&gt;450,000원~700,000원&lt;/td&gt;
&lt;td&gt;100,000원~160,000원&lt;/td&gt;
&lt;td&gt;100,000원~150,000원&lt;/td&gt;
&lt;td&gt;&lt;b&gt;1,100,000원~1,700,000원&lt;/b&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;100,000원~180,000원&lt;/td&gt;
&lt;td&gt;320,000원~470,000원&lt;/td&gt;
&lt;td&gt;420,000원~660,000원&lt;/td&gt;
&lt;td&gt;90,000원~150,000원&lt;/td&gt;
&lt;td&gt;90,000원~140,000원&lt;/td&gt;
&lt;td&gt;&lt;b&gt;1,000,000원~1,600,000원&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;일반 카센터&lt;/td&gt;
&lt;td&gt;대체&amp;middot;재생 선택 폭 큼&lt;/td&gt;
&lt;td&gt;80,000원~160,000원&lt;/td&gt;
&lt;td&gt;280,000원~420,000원&lt;/td&gt;
&lt;td&gt;380,000원~600,000원&lt;/td&gt;
&lt;td&gt;80,000원~140,000원&lt;/td&gt;
&lt;td&gt;80,000원~120,000원&lt;/td&gt;
&lt;td&gt;&lt;b&gt;900,000원~1,400,000원&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;sec-guides&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;07&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;관련 가이드&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;lfunderprice_links&quot;&gt;&lt;a class=&quot;lfunderprice_link&quot; href=&quot;#&quot; data-modal=&quot;noise&quot;&gt;하체 소음 빠른 진단 체크리스트&lt;/a&gt; &lt;a class=&quot;lfunderprice_link&quot; href=&quot;#&quot; data-modal=&quot;align&quot;&gt;얼라이먼트 판별&amp;middot;세팅 가이드&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;sec-end&quot; class=&quot;lfunderprice_sec&quot;&gt;
&lt;div class=&quot;lfunderprice_head&quot;&gt;
&lt;div class=&quot;lfunderprice_titlebar&quot;&gt;
&lt;div class=&quot;lfunderprice_num&quot;&gt;08&lt;/div&gt;
&lt;h2 class=&quot;lfunderprice_h2&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class=&quot;lfunderprice_p&quot; data-ke-size=&quot;size16&quot;&gt;LF소나타는 링크&amp;middot;타이로드엔드&amp;middot;로워암을 세트로 점검하고, 교체 뒤 얼라이먼트를 진행하면 체감 개선이 큽니다. VIN으로 부품번호를 대조해 과잉 정비 없이 정확히 수리하고, 작업 사진과 측정지를 보관해 사후 관리까지 준비하세요.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;lfunderprice_mask&quot; class=&quot;lfunderprice_modal_mask&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div id=&quot;lfunderprice_modal&quot; class=&quot;lfunderprice_modal&quot;&gt;
&lt;div class=&quot;lfunderprice_modal_panel&quot;&gt;
&lt;div class=&quot;lfunderprice_modal_hd&quot;&gt;
&lt;div id=&quot;lfunderprice_modal_title&quot; class=&quot;lfunderprice_modal_tit&quot;&gt;가이드&lt;/div&gt;
&lt;button id=&quot;lfunderprice_close&quot; class=&quot;lfunderprice_x&quot;&gt;닫기&lt;/button&gt;&lt;/div&gt;
&lt;div id=&quot;lfunderprice_modal_body&quot; class=&quot;lfunderprice_modal_bd&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
    (function(){
      document.querySelectorAll(&quot;.lfunderprice_card&quot;).forEach(function(c,i){setTimeout(function(){c.style.opacity=1},70*i)});

      var el=function(id){return document.getElementById(id)};
      var mask=el(&quot;lfunderprice_mask&quot;),modal=el(&quot;lfunderprice_modal&quot;),title=el(&quot;lfunderprice_modal_title&quot;),body=el(&quot;lfunderprice_modal_body&quot;),close=el(&quot;lfunderprice_close&quot;);

      var guides={
        noise:{
          title:&quot;하체 소음 빠른 진단 체크리스트&quot;,
          overview:&quot;소리 위치·속도·노면 조건으로 의심 부품을 빠르게 좁힙니다.&quot;,
          table:[[&quot;소리/상황&quot;,&quot;의심 부품&quot;,&quot;현장 테스트&quot;],
                 [&quot;요철 덜컹&quot;,&quot;스태빌라이저 링크·로워암 부싱&quot;,&quot;저속 방지턱 반복 통과&quot;],
                 [&quot;코너 딱딱&quot;,&quot;드라이브샤프트&quot;,&quot;좌/우 최대 조향 원주 회전&quot;],
                 [&quot;직진 떨림&quot;,&quot;타이로드엔드·얼라이먼트&quot;,&quot;고속 직진과 급제동 관찰&quot;]],
          steps:[&quot;주행 조건(속도·조향각·노면) 기록&quot;,&quot;부츠·부싱·그리스 시각 점검&quot;,&quot;유격 테스트(바·레버 사용)&quot;,&quot;단품 또는 세트 교체 판단&quot;,&quot;정비 후 동일 조건 재점검&quot;],
          notes:[&quot;점검 공임은 무료~30,000원 범위가 일반적입니다.&quot;],
          keywords:[&quot;LF소나타 하체 소음&quot;,&quot;링크 소리 테스트&quot;,&quot;로워암 부싱 교체 시기&quot;]
        },
        align:{
          title:&quot;얼라이먼트 판별·세팅 가이드&quot;,
          overview:&quot;직진 불안·쏠림·편마모를 수치로 교정하는 절차입니다.&quot;,
          table:[[&quot;증상&quot;,&quot;가능 원인&quot;,&quot;우선 확인&quot;],
                 [&quot;쏠림·직진 불안&quot;,&quot;토·캠버 불량, 타이로드·로워암 유격&quot;,&quot;하체 유격 후 측정지 확인&quot;],
                 [&quot;편마모(안쪽·바깥쪽)&quot;,&quot;캠버·캐스터 불균형, 댐퍼 노후&quot;,&quot;마모 패턴 촬영&quot;],
                 [&quot;고속 떨림&quot;,&quot;언밸런스, 허브/조인트 문제&quot;,&quot;휠 밸런스 후 허브 점검&quot;]],
          steps:[&quot;하체 유격 유무 확인&quot;,&quot;타이어 공기압과 마모 패턴 기록&quot;,&quot;측정지(토·캠버·캐스터) 전/후 값 보관&quot;,&quot;하중이 실린 상태에서 체결 토크 재확인&quot;,&quot;100km 주행 후 재측정 예약&quot;],
          notes:[&quot;블루핸즈 100,000원~150,000원, 오토큐 90,000원~140,000원, 일반 카센터 80,000원~120,000원&quot;],
          keywords:[&quot;LF소나타 얼라이먼트 수치&quot;,&quot;쏘나타 편마모 원인&quot;,&quot;얼라이먼트 각도 해석&quot;]
        }
      };

      function smallTable(rows){
        var h=&quot;&lt;table class='lfunderprice_table_small'&gt;&lt;thead&gt;&lt;tr&gt;&quot;;
        rows[0].forEach(function(th){h+=&quot;&lt;th&gt;&quot;+th+&quot;&lt;/th&gt;&quot;});h+=&quot;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&quot;;
        rows.slice(1).forEach(function(r){h+=&quot;&lt;tr&gt;&quot;+r.map(function(td){return &quot;&lt;td&gt;&quot;+td+&quot;&lt;/td&gt;&quot;}).join(&quot;&quot;)+&quot;&lt;/tr&gt;&quot;});h+=&quot;&lt;/tbody&gt;&lt;/table&gt;&quot;;
        return h;
      }

      function openGuide(key){
        var g=guides[key]; if(!g) return;
        title.textContent=g.title;
        var html=&quot;&lt;div class='lfunderprice_grid2'&gt;&quot;;
        html+=&quot;&lt;div class='lfunderprice_sectionbox'&gt;&lt;div class='lfunderprice_h3'&gt;개요&lt;/div&gt;&lt;div class='lfunderprice_p'&gt;&quot;+g.overview+&quot;&lt;/div&gt;&quot;+smallTable(g.table)+&quot;&lt;/div&gt;&quot;;
        html+=&quot;&lt;div class='lfunderprice_sectionbox'&gt;&lt;div class='lfunderprice_h3'&gt;실행 절차&lt;/div&gt;&lt;ul class='lfunderprice_list'&gt;&quot;+g.steps.map(function(s){return &quot;&lt;li&gt;&quot;+s+&quot;&lt;/li&gt;&quot;}).join(&quot;&quot;)+&quot;&lt;/ul&gt;&lt;div class='lfunderprice_h3'&gt;비용 참고·주의&lt;/div&gt;&lt;ul class='lfunderprice_list'&gt;&quot;+g.notes.map(function(s){return &quot;&lt;li&gt;&quot;+s+&quot;&lt;/li&gt;&quot;}).join(&quot;&quot;)+&quot;&lt;/ul&gt;&lt;div class='lfunderprice_h3'&gt;검색 키워드&lt;/div&gt;&lt;div class='lfunderprice_kw'&gt;&quot;+g.keywords.map(function(k){return &quot;&lt;span&gt;&quot;+k+&quot;&lt;/span&gt;&quot;}).join(&quot;&quot;)+&quot;&lt;/div&gt;&lt;/div&gt;&quot;;
        html+=&quot;&lt;/div&gt;&quot;;
        body.innerHTML=html;
        mask.style.display=&quot;block&quot;; modal.style.display=&quot;flex&quot;; document.body.style.overflow=&quot;hidden&quot;;
      }

      function closeGuide(){mask.style.display=&quot;none&quot;;modal.style.display=&quot;none&quot;;document.body.style.overflow=&quot;&quot;}
      close.addEventListener(&quot;click&quot;,closeGuide);
      mask.addEventListener(&quot;click&quot;,closeGuide);
      document.querySelectorAll(&quot;.lfunderprice_link&quot;).forEach(function(a){a.addEventListener(&quot;click&quot;,function(e){e.preventDefault();openGuide(a.getAttribute(&quot;data-modal&quot;))})});
    })();
  &lt;/script&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
  {&quot;@context&quot;:&quot;https://schema.org&quot;,&quot;@type&quot;:&quot;FAQPage&quot;,&quot;mainEntity&quot;:[
    {&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;링크/로워암 교체 후 얼라이먼트는 꼭 필요한가요?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;각도가 변하므로 권장합니다. 직진성과 편마모에 직접적입니다.&quot;}},
    {&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;재생·대체 부품을 써도 되나요?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;가능합니다. 보증 기간과 품질 편차를 확인하고, NVH에 민감하면 순정이 안전합니다.&quot;}},
    {&quot;@type&quot;:&quot;Question&quot;,&quot;name&quot;:&quot;VIN으로 내 차 부품번호는 어떻게 찾나요?&quot;,&quot;acceptedAnswer&quot;:{&quot;@type&quot;:&quot;Answer&quot;,&quot;text&quot;:&quot;블루핸즈·오토큐에 VIN 또는 차대번호를 전달해 EPC로 조회하고, 작업 전에 실제 박스 번호와 대조합니다.&quot;}}
  ]}
  &lt;/script&gt;
&lt;/section&gt;</description>
      <category>DailyRoutine/Car</category>
      <category>VIN으로 부품번호 조회방법</category>
      <category>드라이브샤프트 교체비용</category>
      <category>로워암 부싱 교체</category>
      <category>블루핸즈 정비비용 비교</category>
      <category>스태빌라이저 링크 증상</category>
      <category>얼라이먼트 필요성</category>
      <category>자동차 소음 진단 가이드</category>
      <category>자동차 하체정비 비용표</category>
      <category>타이로드엔드 유격 점검</category>
      <category>하체소음</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/557</guid>
      <comments>https://odinbox.tistory.com/557#entry557comment</comments>
      <pubDate>Mon, 27 Oct 2025 14:01:27 +0900</pubDate>
    </item>
    <item>
      <title>SQL 재귀 쿼리 완전 정리</title>
      <link>https://odinbox.tistory.com/556</link>
      <description>&lt;div id=&quot;sg-recursive&quot;&gt;
&lt;style&gt;
  #sg-recursive{
    --ink:#0f172a;--muted:#64748b;--brand:#0b5bd3;--accent:#23c1ff;--line:#e2e8f0;--chip:#f1f5f9;--panel:#ffffff;
    font-family:&quot;Noto Sans KR&quot;,Pretendard,ui-sans-serif,system-ui,sans-serif;color:var(--ink)
  }
  #sg-recursive .sg-wrap{max-width:1000px;margin:0 auto;padding:28px 18px}
  #sg-recursive .sg-hero{padding:22px 18px;border-radius:18px;background:
    linear-gradient(135deg,rgba(11,91,211,.08),rgba(35,193,255,.08));border:1px solid rgba(11,91,211,.18)}
  #sg-recursive h1{font-weight:900;letter-spacing:-.01em;font-size:clamp(1.6rem,3.2vw,2.15rem);color:#0b3a8a;margin:0}
  #sg-recursive .sg-sub{margin-top:8px;color:var(--muted)}
  #sg-recursive .sg-rule{height:3px;width:90px;background:linear-gradient(90deg,var(--brand),var(--accent));border-radius:3px;margin:14px 0}
  #sg-recursive h2{margin:26px 0 10px;font-size:clamp(1.22rem,2.2vw,1.5rem);color:#0b3a8a;font-weight:800}
  #sg-recursive h3{margin:18px 0 8px;font-size:clamp(1.04rem,1.8vw,1.16rem);font-weight:700;color:#0b3a8a}
  #sg-recursive p,#sg-recursive ul,#sg-recursive ol{margin:10px 0}
  #sg-recursive a{color:#0b3a8a;text-decoration:none;border-bottom:1px dashed rgba(11,91,211,.35)}
  #sg-recursive a:hover{text-decoration:underline}
  #sg-recursive .sg-card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px 16px;box-shadow:0 10px 30px rgba(2,6,23,.06)}
  #sg-recursive .sg-toc{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
  #sg-recursive .sg-chip{display:inline-block;padding:6px 10px;border-radius:999px;background:var(--chip);border:1px solid var(--line);font-weight:600;font-size:.86rem}
  #sg-recursive .sg-badge{display:inline-block;padding:6px 10px;border-radius:999px;background:linear-gradient(90deg,var(--brand),var(--accent));color:#fff;font-weight:700;font-size:.82rem}
  #sg-recursive pre{background:#0b1220;color:#e8edf7;padding:16px;border-radius:12px;overflow:auto;font-size:.93rem;line-height:1.6;margin-top:8px}
  #sg-recursive code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
  #sg-recursive .sg-ol{list-style:none !important;counter-reset:item;margin:8px 0 4px 0;padding-left:0}
  #sg-recursive .sg-ol li{list-style:none !important;margin:6px 0;padding-left:30px;position:relative;color:#334155}
  #sg-recursive .sg-ol li::before{counter-increment:item;content:counter(item) &quot;.&quot;;position:absolute;left:0;top:0;color:#0b5bd3;font-weight:700}
  #sg-recursive .sg-note{background:#f8fbff;border:1px dashed #c8e6ff;border-radius:10px;padding:12px 14px}
  #sg-recursive .sg-reveal{opacity:0;transform:translateY(12px);transition:opacity .8s ease,transform .8s ease}
  #sg-recursive .sg-reveal.sg-in{opacity:1;transform:none}
  #sg-recursive .sg-org,#sg-recursive .sg-org ul{list-style:none !important;margin:0;padding-left:0 !important}
  #sg-recursive .sg-org li{list-style:none !important;position:relative;padding:6px 0 6px 22px}
  #sg-recursive .sg-org li::before{content:&quot;&quot;;position:absolute;top:0;left:0;border-left:2px solid #d1d5db;height:100%}
  #sg-recursive .sg-org li::after{content:&quot;&quot;;position:absolute;top:16px;left:0;border-top:2px solid #d1d5db;width:20px}
  #sg-recursive .sg-org li:last-child::before{height:16px}
  #sg-recursive .sg-divider{height:1px;background:linear-gradient(90deg,rgba(11,91,211,.25),rgba(35,193,255,.25));margin:22px 0}
  #sg-recursive .sg-small{font-size:.92rem;color:#4b5563}
  #sg-recursive .sg-tiny{font-size:.8rem;color:#6b7280}
  #sg-recursive .sg-footer{margin-top:28px;padding-top:10px;border-top:1px solid var(--line)}
  #sg-recursive table.sg-tb{width:100%;border-collapse:collapse;margin:10px 0;font-size:.92rem}
  #sg-recursive table.sg-tb th,#sg-recursive table.sg-tb td{border:1px solid var(--line);padding:8px 10px;text-align:left;vertical-align:top}
  #sg-recursive table.sg-tb th{background:#f4f8ff;color:#0b3a8a;font-weight:700}
  #sg-recursive .sg-thumb{max-width:960px;margin:14px auto 22px;padding:10px;border-radius:22px;background:linear-gradient(135deg,rgba(11,91,211,.06),rgba(35,193,255,.06));border:1px solid rgba(11,91,211,.18);box-shadow:0 16px 40px rgba(2,6,23,.08)}
  #sg-recursive .sg-thumb .sg-thumb-inner{position:relative;border-radius:16px;overflow:hidden;background:#0b1220}
  #sg-recursive .sg-thumb img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;transform:scale(1.001)}
  #sg-recursive .sg-thumb .sg-glow{position:absolute;inset:0;pointer-events:none;background:radial-gradient(1200px 200px at 50% 0,rgba(35,193,255,.20),transparent 60%)}
  @media (max-width:640px){
    #sg-recursive .sg-wrap{padding:22px 14px}
    #sg-recursive pre{font-size:.9rem}
    #sg-recursive .sg-toc{grid-template-columns:1fr}
    #sg-recursive .sg-thumb{margin:10px auto 18px;padding:8px;border-radius:18px}
    #sg-recursive .sg-thumb .sg-thumb-inner{border-radius:14px}
  }
  &lt;/style&gt;
&lt;div class=&quot;sg-wrap&quot;&gt;
&lt;section class=&quot;sg-hero sg-reveal&quot;&gt;&lt;span class=&quot;sg-badge&quot;&gt;SQL &amp;middot; 계층형 데이터&lt;/span&gt;
&lt;h1&gt;SQL 재귀 쿼리: 개념부터 DBMS별 작성법까지 완전 정리&lt;/h1&gt;
&lt;p class=&quot;sg-sub&quot; data-ke-size=&quot;size16&quot;&gt;SQL 재귀 쿼리(WITH RECURSIVE)와 Oracle CONNECT BY를 조직도 예제로 비교하며, 계층형 데이터 탐색&amp;middot;무한 재귀 방지&amp;middot;경로/깊이/상하위 조회 패턴을 PostgreSQL &amp;middot; Oracle &amp;middot; MySQL 8.0 기준으로 정리합니다.&lt;/p&gt;
&lt;div class=&quot;sg-rule&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;sg-reveal&quot;&gt;
&lt;div class=&quot;sg-thumb&quot;&gt;
&lt;div class=&quot;sg-thumb-inner&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;SQL 재귀 쿼리 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bygxS8/dJMb9WyF37v/TuQ7pUmxIGnKfRnk7FtChk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bygxS8/dJMb9WyF37v/TuQ7pUmxIGnKfRnk7FtChk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bygxS8/dJMb9WyF37v/TuQ7pUmxIGnKfRnk7FtChk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbygxS8%2FdJMb9WyF37v%2FTuQ7pUmxIGnKfRnk7FtChk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;SQL 재귀 쿼리 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;sg-glow&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;sg-reveal sg-card&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;div class=&quot;sg-toc&quot;&gt;
&lt;div&gt;&lt;a href=&quot;#sg-top&quot;&gt;재귀 쿼리란&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-why&quot;&gt;재귀 쿼리가 필요한 이유&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-model&quot;&gt;재귀 CTE 동작 모델&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-infinite&quot;&gt;무한 재귀 원인과 방지&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-schema&quot;&gt;예제 스키마와 데이터&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-pg&quot;&gt;PostgreSQL 작성법&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-oracle&quot;&gt;Oracle 작성법&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-mysql&quot;&gt;MySQL 8.0 작성법&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-compare&quot;&gt;DBMS별 비교 요약&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-patterns&quot;&gt;실전 패턴 모음&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-end&quot;&gt;마무리&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;#sg-refs&quot;&gt;참조 문서&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;sg-reveal&quot;&gt;
&lt;h2 id=&quot;sg-top&quot; data-ke-size=&quot;size26&quot;&gt;재귀 쿼리란&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL 재귀 쿼리는 자기 자신을 참조하여 계층 구조를 단계적으로 확장하는 질의 방식입니다. 반복적인 자기 조인을 줄이고, 깊이가 달라져도 동일한 패턴으로 전체 트리를 탐색합니다. 표준 SQL에서는 &lt;code&gt;WITH RECURSIVE&lt;/code&gt; CTE 형태로 제공되며, Oracle은 추가로 &lt;code&gt;CONNECT BY&lt;/code&gt; 구문을 제공합니다. 이 글은 &quot;SQL 계층형 쿼리를 어떻게 작성하는가&quot;, &quot;WITH RECURSIVE와 CONNECT BY는 무엇이 다른가&quot;를 조직도 예제로 직접 비교하며 설명합니다.&lt;/p&gt;
&lt;p class=&quot;sg-small&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;sg-chip&quot;&gt;핵심 개념&lt;/span&gt; 앵커(초기 집합), 재귀(자기참조), 종료(새 행이 없을 때)의 조합으로 트리를 완성합니다. 데이터가 바뀌어도 쿼리 구조가 유지되므로 재사용성이 높습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-why&quot; class=&quot;sg-reveal&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;재귀 쿼리가 필요한 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조직도, 제품 BOM(부품 구성), 댓글 트리, 폴더 구조처럼 부모와 자식 관계가 연쇄적으로 이어지는 데이터는 깊이가 일정하지 않습니다. 전통적인 조인은 깊이만큼 FROM/JOIN 절을 늘려야 하며, 깊이가 변하면 쿼리를 다시 작성해야 합니다. 재귀 쿼리는 동일한 템플릿으로 모든 깊이를 순회하므로 유지보수 비용을 안정적으로 낮춥니다.&lt;/p&gt;
&lt;ol class=&quot;sg-ol sg-small&quot; style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;유연성: 깊이를 모를 때도 전체 트리를 안정적으로 순회합니다.&lt;/li&gt;
&lt;li&gt;가독성: 앵커와 재귀 단계가 분리되어 의도가 명확합니다.&lt;/li&gt;
&lt;li&gt;확장성: 경로, 깊이, 루트&amp;middot;말단 여부 등 부가 정보를 쉽게 도출합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-model&quot; class=&quot;sg-reveal&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;재귀 CTE 동작 모델&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재귀 CTE는 &lt;code&gt;WITH RECURSIVE cte AS (앵커 UNION ALL 재귀)&lt;/code&gt; 형태로 작성합니다. 내부 실행은 다음과 같습니다.&lt;/p&gt;
&lt;ol class=&quot;sg-ol&quot; style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;앵커 단계에서 루트 후보를 한 번 조회하여 작업 집합에 적재합니다.&lt;/li&gt;
&lt;li&gt;재귀 단계에서 직전 단계 결과를 입력으로 사용해 자식 행을 찾고 누적합니다.&lt;/li&gt;
&lt;li&gt;새로운 행이 더 이상 생성되지 않으면 반복이 종료되고 누적 결과를 반환합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;sg-note sg-small&quot;&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;&lt;b&gt;UNION ALL vs UNION&lt;/b&gt;: ALL은 중복 제거가 없어 빠릅니다. 중복이나 순환 가능성이 있으면 &lt;code&gt;UNION&lt;/code&gt; 또는 별도 차단 로직을 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정렬&lt;/b&gt;: 출력 순서는 엔진 구현에 좌우됩니다. 사용자 표시용 순서가 필요하면 &lt;code&gt;ORDER BY&lt;/code&gt;를 명시합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인덱스&lt;/b&gt;: 재귀부 조인 키(&lt;code&gt;manager_id&lt;/code&gt; 등)에 인덱스가 없으면 반복 스캔 비용이 급증합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;깊이 제한&lt;/b&gt;: 오류나 순환으로 인한 증폭을 막기 위해 &lt;code&gt;lvl &amp;lt; N&lt;/code&gt; 같은 제한을 둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-infinite&quot; class=&quot;sg-reveal sg-card&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;무한 재귀 원인과 방지&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;원인&lt;/h3&gt;
&lt;ul class=&quot;sg-small&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;종료 조건이 없어 탐색이 끝나지 않는 경우&lt;/li&gt;
&lt;li&gt;A&amp;rarr;B&amp;rarr;C&amp;rarr;A처럼 동일 노드를 재방문하는 순환 데이터&lt;/li&gt;
&lt;li&gt;동일 노드가 여러 경로에서 반복 추가되는 중복 누적&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;방지 전략&lt;/h3&gt;
&lt;ul class=&quot;sg-small&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;lvl&lt;/code&gt; 기반 깊이 제한&lt;/li&gt;
&lt;li&gt;경로 문자열 또는 배열에 방문 이력 기록 후 재방문 차단&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UNION&lt;/code&gt;으로 중복 제거 또는 표준 &lt;code&gt;CYCLE&lt;/code&gt; 절 사용(지원 DBMS)&lt;/li&gt;
&lt;li&gt;Oracle &lt;code&gt;CONNECT BY NOCYCLE&lt;/code&gt;, PostgreSQL&amp;middot;Oracle &lt;code&gt;SEARCH&lt;/code&gt;/&lt;code&gt;CYCLE&lt;/code&gt; 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-schema&quot; class=&quot;sg-reveal&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예제 스키마와 데이터&lt;/h2&gt;
&lt;div class=&quot;sg-note sg-small&quot;&gt;직원 조직도 예시를 사용합니다. 한 직원은 0명 또는 1명의 상사를 가지며 상사가 없으면 루트입니다.&lt;/div&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;CREATE TABLE employees (
  emp_id     INT PRIMARY KEY,
  name       VARCHAR(50),
  manager_id INT
);

INSERT INTO employees VALUES
  (1,'김하늘',NULL),
  (2,'박준호',1),
  (3,'이서연',1),
  (4,'최민수',2),
  (5,'장예린',2);

CREATE INDEX ix_employees_manager ON employees(manager_id);&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;sg-small&quot; data-ke-size=&quot;size16&quot;&gt;핵심 키는 &lt;code&gt;manager_id&lt;/code&gt;입니다. 이 값으로 부모에서 자식으로 탐색하므로 인덱스를 반드시 생성합니다. 위 데이터에서 김하늘이 루트(lvl 1), 박준호&amp;middot;이서연이 그 자식(lvl 2), 최민수&amp;middot;장예린이 박준호의 자식(lvl 3)입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-pg&quot; class=&quot;sg-reveal&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;PostgreSQL 작성법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기본 재귀 CTE&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH RECURSIVE org(emp_id, name, manager_id, lvl) AS (
  SELECT emp_id, name, manager_id, 1
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id, o.lvl + 1
  FROM employees e
  JOIN org o ON e.manager_id = o.emp_id
)
SELECT emp_id,name,manager_id,lvl
FROM org
ORDER BY lvl, emp_id;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sg-small&quot;&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;앵커는 루트 직원을 가져옵니다.&lt;/li&gt;
&lt;li&gt;재귀부는 &lt;code&gt;e.manager_id = o.emp_id&lt;/code&gt;로 부모와 자식을 연결합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lvl&lt;/code&gt;은 깊이 계산과 깊이 제한 조건에 활용합니다.&lt;/li&gt;
&lt;li&gt;표시 순서가 필요하면 &lt;code&gt;ORDER BY&lt;/code&gt;를 명시합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;경로 누적과 말단 판별&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH RECURSIVE org(emp_id, name, manager_id, path, lvl) AS (
  SELECT emp_id, name, manager_id, name::text, 1
  FROM employees WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id,
         org.path || ' &amp;gt; ' || e.name,
         org.lvl + 1
  FROM employees e
  JOIN org ON e.manager_id = org.emp_id
)
SELECT o.*,
       NOT EXISTS (SELECT 1 FROM employees c WHERE c.manager_id = o.emp_id) AS is_leaf
FROM org o
ORDER BY lvl, emp_id;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sg-small&quot;&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;&lt;code&gt;path&lt;/code&gt;는 루트에서 현재까지의 경로를 문자열로 누적합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NOT EXISTS&lt;/code&gt;로 자식이 없는 노드를 말단으로 식별합니다.&lt;/li&gt;
&lt;li&gt;경로 문자열은 트리 렌더링과 브레드크럼 생성에 유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SEARCH/CYCLE 절&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;WITH RECURSIVE org(emp_id, manager_id) AS (
  SELECT emp_id, manager_id FROM employees WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.manager_id FROM employees e JOIN org o ON e.manager_id = o.emp_id
)
SEARCH BREADTH FIRST BY emp_id SET bfs_ord
CYCLE emp_id SET is_cycle TO TRUE DEFAULT FALSE
SELECT emp_id, manager_id, bfs_ord, is_cycle FROM org;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;sg-small&quot; data-ke-size=&quot;size16&quot;&gt;탐색 순서를 자동 컬럼으로 부여하고, 순환을 표준 문법으로 탐지할 수 있습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-oracle&quot; class=&quot;sg-reveal&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Oracle 작성법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;표준 재귀 CTE&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH org (emp_id, name, manager_id, lvl, path) AS (
  SELECT emp_id, name, manager_id, 1, CAST(name AS VARCHAR2(4000))
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id,
         o.lvl + 1,
         o.path || ' &amp;gt; ' || e.name
  FROM employees e
  JOIN org o ON e.manager_id = o.emp_id
)
SELECT emp_id, name, manager_id, lvl, path
FROM org
ORDER BY lvl, emp_id;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CONNECT BY 계층 쿼리&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT
  emp_id, name, manager_id, LEVEL AS lvl,
  SYS_CONNECT_BY_PATH(name, ' &amp;gt; ') AS path,
  CONNECT_BY_ISLEAF AS is_leaf
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR emp_id = manager_id
ORDER SIBLINGS BY emp_id;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sg-small&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;LEVEL&lt;/code&gt;은 깊이를 자동 제공합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORDER SIBLINGS BY&lt;/code&gt;로 형제 정렬 기준을 지정합니다.&lt;/li&gt;
&lt;li&gt;순환 데이터는 &lt;code&gt;NOCYCLE&lt;/code&gt;과 &lt;code&gt;CONNECT_BY_ISCYCLE&lt;/code&gt;로 제어합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-mysql&quot; class=&quot;sg-reveal&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MySQL 8.0 작성법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기본 재귀 CTE&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH RECURSIVE org(emp_id, name, manager_id, lvl) AS (
  SELECT emp_id, name, manager_id, 1
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id, o.lvl + 1
  FROM employees e
  JOIN org o ON e.manager_id = o.emp_id
)
SELECT emp_id,name,manager_id,lvl
FROM org
ORDER BY lvl, emp_id;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문자열 경로 기반 순환 차단&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH RECURSIVE org(emp_id, name, manager_id, path, lvl) AS (
  SELECT emp_id, name, manager_id, CONCAT('/', emp_id, '/'), 1
  FROM employees WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id,
         CONCAT(o.path, e.emp_id, '/'),
         o.lvl + 1
  FROM employees e
  JOIN org o ON e.manager_id = o.emp_id
  WHERE INSTR(o.path, CONCAT('/', e.emp_id, '/')) = 0
)
SELECT emp_id,name,manager_id,lvl FROM org;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sg-small&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표준 &lt;code&gt;CYCLE&lt;/code&gt; 절이 없으므로 경로 문자열로 재방문을 차단합니다.&lt;/li&gt;
&lt;li&gt;대규모 데이터에서는 JSON 경로와 가상 컬럼 인덱스를 고려할 수 있습니다.&lt;/li&gt;
&lt;li&gt;MySQL 8.0 미만(5.7 이하)에서는 재귀 CTE를 지원하지 않으므로, 저장 프로시저나 인접 리스트 반복 조회로 우회해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-compare&quot; class=&quot;sg-reveal sg-card&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DBMS별 비교 요약&lt;/h2&gt;
&lt;table class=&quot;sg-tb&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;Oracle&lt;/th&gt;
&lt;th&gt;MySQL 8.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WITH RECURSIVE&lt;/td&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;CONNECT BY&lt;/td&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;직접 lvl 계산&lt;/td&gt;
&lt;td&gt;LEVEL 제공&lt;/td&gt;
&lt;td&gt;직접 lvl 계산&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;순환 차단 표준 문법&lt;/td&gt;
&lt;td&gt;SEARCH / CYCLE&lt;/td&gt;
&lt;td&gt;NOCYCLE / CYCLE&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;SYS_CONNECT_BY_PATH&lt;/td&gt;
&lt;td&gt;CONCAT 누적&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p class=&quot;sg-small&quot; data-ke-size=&quot;size16&quot;&gt;정리하면, 표준 &lt;code&gt;WITH RECURSIVE&lt;/code&gt;는 세 DBMS에서 모두 동작하므로 이식성이 가장 좋습니다. Oracle은 &lt;code&gt;CONNECT BY&lt;/code&gt;로 더 간결하게 작성할 수 있고, MySQL은 표준 순환 차단 문법이 없어 경로 문자열로 직접 막아야 한다는 점이 가장 큰 차이입니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-patterns&quot; class=&quot;sg-reveal sg-card&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실전 패턴 모음&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;특정 노드의 전체 하위&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH RECURSIVE sub(emp_id, name, manager_id, lvl) AS (
  SELECT emp_id, name, manager_id, 0 FROM employees WHERE emp_id = :target_id
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id, s.lvl + 1
  FROM employees e JOIN sub s ON e.manager_id = s.emp_id
)
SELECT emp_id,name,manager_id,lvl FROM sub;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;현재 노드에서 루트까지 상위 경로&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WITH RECURSIVE up(emp_id, name, manager_id, path, lvl) AS (
  SELECT emp_id, name, manager_id, name, 0
  FROM employees WHERE emp_id = :current_id
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id, CONCAT(e.name,' &amp;gt; ',up.path), up.lvl + 1
  FROM employees e JOIN up ON up.manager_id = e.emp_id
)
SELECT * FROM up;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sg-divider&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;조직도 구조 예시&lt;/h3&gt;
&lt;p class=&quot;sg-small&quot; data-ke-size=&quot;size16&quot;&gt;괄호 안 숫자는 &lt;code&gt;lvl&lt;/code&gt;(깊이)입니다. 위 예제 데이터를 트리로 표현하면 다음과 같습니다.&lt;/p&gt;
&lt;ul class=&quot;sg-org sg-small&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;김하늘 (lvl 1, 루트)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;박준호 (lvl 2)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최민수 (lvl 3, 말단)&lt;/li&gt;
&lt;li&gt;장예린 (lvl 3, 말단)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이서연 (lvl 2, 말단)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-end&quot; class=&quot;sg-reveal sg-card&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p class=&quot;sg-small&quot; data-ke-size=&quot;size16&quot;&gt;재귀 쿼리는 강력하지만 작성 방식과 데이터 특성에 따라 결과와 성능이 크게 달라질 수 있습니다. 이 글은 재귀 쿼리를 이해하는 과정에서 헷갈렸던 개념과 작동 흐름을 정리하기 위해 작성했습니다. 예제는 이해를 돕기 위한 최소 구성으로 제시했으며, 실제 환경에서는 스키마 구조, 데이터량, 인덱스 전략, 순환 규칙에 맞춘 세부 튜닝이 필요합니다. 글에서 부정확한 부분이나 보완할 내용이 있다면 댓글로 알려 주시면 감사하겠습니다. 의견을 반영하여 내용을 지속적으로 업데이트하겠습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;sg-refs&quot; class=&quot;sg-reveal sg-footer&quot;&gt;
&lt;div class=&quot;sg-tiny&quot;&gt;참조 문서&lt;/div&gt;
&lt;ul class=&quot;sg-tiny&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-RECURSIVE&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PostgreSQL: Recursive Queries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Recursive-Subquery-Factoring.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Oracle: Recursive Subquery Factoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Hierarchical-Queries.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Oracle: Hierarchical Queries (CONNECT BY)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/with.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MySQL 8.0: Common Table Expressions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{
  &quot;@context&quot;:&quot;https://schema.org&quot;,
  &quot;@type&quot;:&quot;TechArticle&quot;,
  &quot;headline&quot;:&quot;SQL 재귀 쿼리: 개념부터 DBMS별 작성법까지 완전 정리&quot;,
  &quot;about&quot;:[&quot;SQL 재귀 쿼리&quot;,&quot;WITH RECURSIVE&quot;,&quot;CONNECT BY&quot;,&quot;계층형 데이터&quot;,&quot;PostgreSQL&quot;,&quot;Oracle&quot;,&quot;MySQL&quot;],
  &quot;inLanguage&quot;:&quot;ko&quot;,
  &quot;audience&quot;:{&quot;@type&quot;:&quot;Audience&quot;,&quot;audienceType&quot;:&quot;개발자&quot;},
  &quot;keywords&quot;:&quot;재귀 CTE, WITH RECURSIVE, CONNECT BY, 계층형 데이터, 조직도, 무한 재귀, SEARCH CYCLE&quot;,
  &quot;author&quot;:{&quot;@type&quot;:&quot;Person&quot;,&quot;name&quot;:&quot;최영환&quot;},
  &quot;publisher&quot;:{&quot;@type&quot;:&quot;Organization&quot;,&quot;name&quot;:&quot;OdinBOX&quot;}
}
&lt;/script&gt;
&lt;script&gt;
(function(){
  var root=document.getElementById('sg-recursive'); if(!root)return;
  var els=root.querySelectorAll('.sg-reveal');
  if(!('IntersectionObserver'in window)){els.forEach(function(el){el.classList.add('sg-in')});return;}
  var io=new IntersectionObserver(function(entries){
    entries.forEach(function(e){ if(e.isIntersecting){e.target.classList.add('sg-in');io.unobserve(e.target);} });
  },{threshold:0.12});
  els.forEach(function(el){io.observe(el)});
})();
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>CONNNECTBY</category>
      <category>CTE</category>
      <category>MYSQL</category>
      <category>oraclesql</category>
      <category>PostgreSQL</category>
      <category>SQL</category>
      <category>WITHRECURSIVE</category>
      <category>계층형데이터</category>
      <category>데이터베이스</category>
      <category>재귀쿼리</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/556</guid>
      <comments>https://odinbox.tistory.com/556#entry556comment</comments>
      <pubDate>Sat, 25 Oct 2025 14:40:38 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL, 논리복제 실무 가이드</title>
      <link>https://odinbox.tistory.com/555</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{
  &quot;@context&quot;: &quot;https://schema.org&quot;,
  &quot;@type&quot;: &quot;TechArticle&quot;,
  &quot;headline&quot;: &quot;PostgreSQL 15 논리 복제 실무 가이드&quot;,
  &quot;inLanguage&quot;: &quot;ko&quot;,
  &quot;about&quot;: &quot;PostgreSQL 15 logical replication&quot;,
  &quot;author&quot;: {&quot;@type&quot;:&quot;Person&quot;,&quot;name&quot;:&quot;OdinBOX&quot;},
  &quot;datePublished&quot;: &quot;2025-10-18&quot;
}
&lt;/script&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;style&gt;
:root{
  --fg:#0b1220;--fg2:#2a3140;--muted:#667085;--border:#e6e9f0;--soft:#f6f8fc;
  --accent:#2f6feb;--accent2:#00b894;--accent3:#7c3aed;
  --card:#fff;--codebg:#0b1220;--codebd:#101a33
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:#fff;color:var(--fg);font-family:-apple-system,BlinkMacSystemFont,&quot;Noto Sans KR&quot;,Roboto,&quot;Segoe UI&quot;,Helvetica,Arial,sans-serif;line-height:1.85;word-break:keep-all}
.pg15-root{max-width:1100px;margin:auto;padding:clamp(16px,2vw,32px)}
.pg15-title{font-size:clamp(28px,2.6vw,44px);font-weight:900;letter-spacing:-.02em;background:linear-gradient(90deg,var(--accent),var(--accent3),var(--accent2));-webkit-background-clip:text;background-clip:text;color:transparent;text-align:center;margin:0 0 6px;animation:titleShift 7s ease-in-out infinite}
@keyframes titleShift{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}
.pg15-sub{text-align:center;color:var(--muted);margin:0 0 18px}
.pg15-imgfx{border-radius:18px;border:1px solid var(--border);overflow:hidden;box-shadow:0 10px 30px rgba(13,35,67,.08);margin:18px auto;max-width:640px;transform:translateY(6px);animation:floatIn .7s cubic-bezier(.22,1,.36,1) both}
.pg15-imgfx img{display:block;width:100%;height:auto}
@keyframes floatIn{from{opacity:0;transform:translateY(16px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}
.pg15-wrap{display:flex;flex-direction:row-reverse;gap:28px}
@media (max-width:1020px){.pg15-wrap{flex-direction:column}}

.pg15-card{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:18px;margin:18px 0;box-shadow:0 8px 24px rgba(16,24,40,.06);animation:fadeUp .55s ease both}
.pg15-card:hover{transform:translateY(-2px);box-shadow:0 16px 36px rgba(16,24,40,.10)}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

.pg15-h2{scroll-margin-top:88px;font-size:clamp(20px,1.6rem,28px);font-weight:900;letter-spacing:-.01em;margin:42px 0 14px;position:relative;padding-left:16px}
.pg15-h2:before{content:&quot;&quot;;position:absolute;left:0;top:.55em;width:8px;height:8px;border-radius:2px;background:linear-gradient(135deg,var(--accent),var(--accent2));box-shadow:0 0 0 6px rgba(47,111,235,.10)}
.pg15-h2:after{content:&quot;&quot;;position:absolute;left:16px;right:0;bottom:-6px;height:3px;border-radius:2px;background:linear-gradient(90deg,var(--accent),var(--accent3));transform:scaleX(0);transform-origin:left;animation:underline .8s .25s cubic-bezier(.22,1,.36,1) forwards}
@keyframes underline{to{transform:scaleX(1)}}

.pg15-h3{font-size:clamp(16px,1.08rem,20px);font-weight:800;color:var(--fg2);margin:22px 0 10px;padding-left:14px;position:relative}
.pg15-h3:before{content:&quot;&quot;;position:absolute;left:0;top:.55em;width:6px;height:6px;background:var(--accent2);border-radius:2px}

.pg15-code{background:var(--codebg);color:#e8eaf2;border:1px solid var(--codebd);border-radius:14px;padding:14px;overflow-x:auto;font-family:ui-monospace,Consolas,Monaco,monospace;font-size:.9rem;margin:10px 0}
.pg15-code:hover{box-shadow:0 0 0 2px rgba(124,58,237,.2) inset}

.pg15-table{width:100%;border-collapse:collapse;margin:10px 0;border-radius:12px;overflow:hidden}
.pg15-table th,.pg15-table td{padding:12px;border-bottom:1px solid #eef1f6;text-align:left}
.pg15-table thead th{background:#f6f8ff;font-weight:800}

.pg15-note{border-left:4px solid var(--accent);background:#f7faff;padding:12px 14px;border-radius:10px;margin:12px 0;animation:glow 2.2s ease-in-out infinite alternate}
@keyframes glow{from{box-shadow:0 0 0 rgba(47,111,235,0)}to{box-shadow:0 8px 22px rgba(47,111,235,.12)}}

.pg15-grid{display:grid;gap:18px;grid-template-columns:1fr 1fr}
@media(max-width:820px){.pg15-grid{grid-template-columns:1fr}}

.pg15-toc{position:sticky;top:16px;margin:18px 0}
.pg15-toc .card{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:16px;box-shadow:0 10px 28px rgba(13,35,67,.06)}
.pg15-toc h2{font-size:1.02rem;margin:0 0 8px;color:#0e1a33}
.pg15-toc ul{list-style:none!important;padding:0;margin:0;display:grid;gap:10px}
.pg15-toc li{list-style:none!important}
.pg15-toc li::marker{content:&quot;&quot;}
.pg15-toc [data-ke-list-type]{list-style:none!important}
.pg15-toc a{position:relative;display:block;padding:10px 12px;border:1px solid var(--border);border-radius:12px;text-decoration:none;color:#0b4ee1;font-weight:700;overflow:hidden}
.pg15-toc a:after{content:&quot;&quot;;position:absolute;inset:0;background:linear-gradient(90deg,rgba(47,111,235,.12),rgba(124,58,237,.12));transform:translateX(-100%);transition:transform .45s cubic-bezier(.22,1,.36,1);pointer-events:none}
.pg15-toc a:hover:after{transform:translateX(0)}
.pg15-toc a:hover{border-color:#cfe0ff;box-shadow:0 6px 14px rgba(24,44,90,.08)}

footer{text-align:center;color:#5c6677;font-size:.95rem;margin-top:40px}

.reveal{opacity:0;transform:translateY(14px);animation:reveal .6s ease forwards}
.reveal:nth-of-type(2){animation-delay:.06s}
.reveal:nth-of-type(3){animation-delay:.12s}
@keyframes reveal{to{opacity:1;transform:none}}

@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
}
&lt;/style&gt;
&lt;/div&gt;
&lt;article class=&quot;pg15-root&quot;&gt;&lt;header&gt;
&lt;h1 class=&quot;pg15-title&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p class=&quot;pg15-sub&quot; data-ke-size=&quot;size16&quot;&gt;FEMS 사례를 바탕으로 개념을 충분히 풀어 설명하고, 옵션의 의미와 설정 방법, 재동기화, 트리거, 모니터링, Tailscale 네트워크 구성까지 단계별로 정리합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKEUzx/dJMb9Nhuo5x/HzqTe63vV0Bwg0Zh2o7rnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKEUzx/dJMb9Nhuo5x/HzqTe63vV0Bwg0Zh2o7rnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKEUzx/dJMb9Nhuo5x/HzqTe63vV0Bwg0Zh2o7rnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKEUzx%2FdJMb9Nhuo5x%2FHzqTe63vV0Bwg0Zh2o7rnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;nav class=&quot;pg15-toc pg15-hide-mobile&quot; aria-label=&quot;목차&quot;&gt;&lt;/nav&gt;&lt;nav class=&quot;pg15-toc pg15-show-mobile&quot; aria-label=&quot;목차&quot;&gt;
&lt;div class=&quot;pg15-card&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;&lt;a href=&quot;#pg15-concept&quot;&gt;개념과 원리&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pg15-setup&quot;&gt;구성 절차&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pg15-reset&quot;&gt;재동기화&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pg15-monitor&quot;&gt;모니터링&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pg15-checklist&quot;&gt;체크리스트&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/nav&gt;&lt;/header&gt;
&lt;section class=&quot;pg15-wrap&quot;&gt;
&lt;div&gt;
&lt;section id=&quot;pg15-concept&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;1. 개념 심화와 동작 원리&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b63ZeB/dJMb9MXbbPP/YNZrKqlEM2F8rKFLaJjfHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b63ZeB/dJMb9MXbbPP/YNZrKqlEM2F8rKFLaJjfHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b63ZeB/dJMb9MXbbPP/YNZrKqlEM2F8rKFLaJjfHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb63ZeB%2FdJMb9MXbbPP%2FYNZrKqlEM2F8rKFLaJjfHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;1) 비유로 이해합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리 복제는 신문 구독과 비슷합니다. 신문사가 오늘자 기사 목록을 만들어 두고, 구독자에게 순서대로 배달합니다. 구독자가 부재중이어도 배달부는 어디까지 전달했는지 기록합니다. PostgreSQL에서는 이 기록이 복제 슬롯입니다.&lt;/p&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;2) 내부 동작을 단계로 설명합니다&lt;/h3&gt;
&lt;ol class=&quot;pg15-steps&quot; style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li class=&quot;pg15-step&quot;&gt;게시자는 커밋 시 변경을 WAL에 기록합니다.&lt;/li&gt;
&lt;li class=&quot;pg15-step&quot;&gt;논리 디코더가 WAL을 테이블/컬럼/값 이벤트로 변환합니다.&lt;/li&gt;
&lt;li class=&quot;pg15-step&quot;&gt;복제 슬롯이 읽은 위치를 저장해 재시작 시 이어갑니다.&lt;/li&gt;
&lt;li class=&quot;pg15-step&quot;&gt;구독자 워커가 이벤트를 수신해 동일 DML을 실행합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;3) 보장과 비보장&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;보장&lt;/b&gt;: 트랜잭션 원자성, 내부 순서, 동일 행 변경 순서.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비보장&lt;/b&gt;: 다중 게시자 전역 순서, DDL 자동 동기화, 시퀀스 동기화.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;4) 복제 대상&lt;/h3&gt;
&lt;div class=&quot;pg15-table&quot;&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;비고&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DML: INSERT, UPDATE, DELETE, TRUNCATE&lt;/td&gt;
&lt;td&gt;복제됨&lt;/td&gt;
&lt;td&gt;Publication 설정 준수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDL: CREATE/ALTER TABLE&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;setval() 보정 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large Object&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;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;5) FEMS 시나리오 적합성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 DB에 안전 적재 후 연결 회복 시 중앙으로 밀어 올립니다. 슬롯이 진행 위치를 기억해 유실을 줄입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-design&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;2. 설계 지침&lt;/h2&gt;
&lt;div class=&quot;pg15-grid&quot;&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;1) 키 설계&lt;/h3&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;불가 시 REPLICA IDENTITY FULL 고려.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;2) 파티션&amp;middot;인덱스&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간 파티셔닝으로 초기 스냅샷&amp;middot;보관 단순화.&lt;/li&gt;
&lt;li&gt;구독자 조회 인덱스 사전 구축.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;3) 타임스탬프&amp;middot;중복 방지&lt;/h3&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;UNIQUE 제약 또는 UPSERT 전략.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-schema&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;3. 실습 스키마&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FEMS 전력 계측 예시로 (site_code, log_time) 복합 기본키를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;pg15-code sql&quot;&gt;&lt;code&gt;CREATE TABLE energy_data (
  site_code     TEXT        NOT NULL,
  usage_kwh     NUMERIC,
  peak_kw       NUMERIC,
  power_factor  NUMERIC,
  log_time      TIMESTAMP   NOT NULL,
  PRIMARY KEY (site_code, log_time)
);&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg15-note&quot;&gt;시퀀스는 복제되지 않습니다. 구독자에서 setval()로 보정합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-settings&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;4. 설정 옵션 상세&lt;/h2&gt;
&lt;div class=&quot;pg15-grid&quot;&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg15-badge&quot;&gt;게시자&lt;/span&gt; postgresql.conf&lt;/h3&gt;
&lt;div class=&quot;pg15-table&quot;&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;wal_level = logical&lt;/td&gt;
&lt;td&gt;논리 디코딩 활성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_wal_senders&lt;/td&gt;
&lt;td&gt;동시 전송 프로세스 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_replication_slots&lt;/td&gt;
&lt;td&gt;복제 슬롯 상한&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;idle_replication_slot_timeout&lt;/td&gt;
&lt;td&gt;미사용 슬롯 정리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;listen_addresses&lt;/td&gt;
&lt;td&gt;Tailscale 사용 시 0.0.0.0 또는 TS IP 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-note&quot;&gt;
&lt;pre class=&quot;pg15-code angelscript&quot;&gt;&lt;code&gt;host    replication    replicator    100.64.0.0/10    md5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;pg15-badge&quot;&gt;구독자&lt;/span&gt; 워커 파라미터&lt;/h3&gt;
&lt;div class=&quot;pg15-table&quot;&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;max_logical_replication_workers&lt;/td&gt;
&lt;td&gt;논리 복제 워커 상한&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_sync_workers_per_subscription&lt;/td&gt;
&lt;td&gt;초기 스냅샷 병렬 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_worker_processes&lt;/td&gt;
&lt;td&gt;전체 워커 상한&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wal_receiver_timeout 등&lt;/td&gt;
&lt;td&gt;불안정 네트워크 보강&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot; style=&quot;background: linear-gradient(180deg,#fff,#f8fbff); border: 1px dashed #cfe0ff;&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;Subscription 옵션&lt;/h3&gt;
&lt;div class=&quot;pg15-table&quot;&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;copy_data&lt;/td&gt;
&lt;td&gt;생성 시 스냅샷 복사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;create_slot&lt;/td&gt;
&lt;td&gt;슬롯 자동 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;enabled&lt;/td&gt;
&lt;td&gt;즉시 시작 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slot_name&lt;/td&gt;
&lt;td&gt;슬롯 이름 고정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;synchronous_commit&lt;/td&gt;
&lt;td&gt;커밋 보장 수준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;binary&lt;/td&gt;
&lt;td&gt;이진 전송 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;streaming&lt;/td&gt;
&lt;td&gt;대용량 트랜잭션 스트리밍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;origin&lt;/td&gt;
&lt;td&gt;특정 원본만 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-setup&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;5. 단계별 구성&lt;/h2&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;5-1 게시자 준비&lt;/h3&gt;
&lt;div class=&quot;pg15-steps&quot;&gt;
&lt;div class=&quot;pg15-step&quot;&gt;&lt;b&gt;복제 계정 생성&lt;/b&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;CREATE ROLE replicator WITH LOGIN ENCRYPTED PASSWORD '강력한_비밀번호';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO replicator;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-step&quot;&gt;&lt;b&gt;파라미터 적용&lt;/b&gt;
&lt;pre class=&quot;pg15-code ini&quot;&gt;&lt;code&gt;wal_level = logical
max_wal_senders = 10
max_replication_slots = 10&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-step&quot;&gt;&lt;b&gt;접속 허용&lt;/b&gt;
&lt;pre class=&quot;pg15-code angelscript&quot;&gt;&lt;code&gt;host replication replicator 100.64.0.0/10 md5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;5-2 Publication 생성&lt;/h3&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;CREATE PUBLICATION fems_pub
  FOR TABLE energy_data
  WITH (publish = 'insert, update, delete, truncate');&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;5-3 구독자 스키마 준비&lt;/h3&gt;
&lt;pre class=&quot;pg15-code sql&quot;&gt;&lt;code&gt;CREATE TABLE energy_data (
  site_code TEXT NOT NULL,
  usage_kwh NUMERIC,
  peak_kw NUMERIC,
  power_factor NUMERIC,
  log_time TIMESTAMP NOT NULL,
  PRIMARY KEY (site_code, log_time)
);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;5-4 Subscription 생성&lt;/h3&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;CREATE SUBSCRIPTION fems_sub
  CONNECTION 'host=100.64.0.10 port=5432 dbname=fems user=replicator password=강력한_비밀번호'
  PUBLICATION fems_pub
  WITH (create_slot = true, enabled = true, copy_data = true);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;5-5 동작 테스트&lt;/h3&gt;
&lt;pre class=&quot;pg15-code sql&quot;&gt;&lt;code&gt;INSERT INTO energy_data(site_code, usage_kwh, peak_kw, power_factor, log_time)
VALUES ('SITE-A', 125.4, 150.0, 0.95, NOW());
SELECT * FROM energy_data ORDER BY log_time DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg15-note&quot;&gt;구독자는 행을 찾지 못하는 UPDATE/DELETE를 건너뜁니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-filters&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;6. 행과 컬럼 필터&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PostgreSQL 15는 컬럼 목록과 행 조건을 동시에 지정하여 부분 복제를 구성합니다.&lt;/p&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;CREATE PUBLICATION fems_pub_site_a
  FOR TABLE energy_data (site_code, usage_kwh, peak_kw, power_factor, log_time)
  WHERE (site_code = 'SITE-A');&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg15-note&quot;&gt;Publication 변경 후 구독자에서 ALTER SUBSCRIPTION ... REFRESH PUBLICATION을 실행합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-initial&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;7. 초기 로딩 전략&lt;/h2&gt;
&lt;div class=&quot;pg15-grid&quot;&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;전부 스냅샷&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 양이 적을 때 적합합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;덤프 후 copy_data=false&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대량 데이터에 적합합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;하이브리드&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;덤프로 구독자를 채움&lt;/li&gt;
&lt;li&gt;enabled=false로 생성&lt;/li&gt;
&lt;li&gt;점검 후 ENABLE&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-reset&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;8. 재동기화와 초기화&lt;/h2&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;절차&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ALTER SUBSCRIPTION fems_sub DISABLE;&lt;/li&gt;
&lt;li&gt;충돌 데이터 정리&lt;/li&gt;
&lt;li&gt;DROP SUBSCRIPTION fems_sub WITH (drop_slot);&lt;/li&gt;
&lt;li&gt;옵션 선택해 재생성&lt;/li&gt;
&lt;li&gt;필요 시 REFRESH PUBLICATION&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;충돌 유형&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;duplicate key: 충돌 행 정리 후 재시도&lt;/li&gt;
&lt;li&gt;외래 키 실패: 초기 적재 순서 조정 또는 임시 제약 비활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-triggers&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;9. 트리거 설계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구독자 적용 워커는 session_replication_role='replica'로 동작합니다. 복제 유입 데이터에 대해 트리거를 실행하려면 ENABLE REPLICA 또는 ENABLE ALWAYS를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;ALTER TABLE energy_data ENABLE REPLICA TRIGGER trg_energy_audit;
ALTER TABLE energy_data ENABLE ALWAYS TRIGGER trg_energy_audit;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg15-note&quot;&gt;복제된 쓰기가 다시 다른 노드로 복제되는 구조는 루프를 유발합니다. 경로를 단방향으로 유지합니다.&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;CREATE TABLE energy_audit (
  at_time TIMESTAMP DEFAULT now(),
  op      TEXT,
  site_code TEXT,
  log_time  TIMESTAMP,
  who       TEXT
);
CREATE OR REPLACE FUNCTION fn_energy_audit() RETURNS trigger AS $$
BEGIN
  INSERT INTO energy_audit(op, site_code, log_time, who)
  VALUES (TG_OP, NEW.site_code, NEW.log_time, current_user);
  RETURN NEW;
END; $$ LANGUAGE plpgsql;
CREATE TRIGGER trg_energy_audit
AFTER INSERT OR UPDATE OR DELETE ON energy_data
FOR EACH ROW EXECUTE FUNCTION fn_energy_audit();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-perf&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;10. 성능과 용량 계획&lt;/h2&gt;
&lt;div class=&quot;pg15-grid&quot;&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;슬롯&amp;middot;WAL&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비활성 슬롯은 WAL 누적 원인&lt;/li&gt;
&lt;li&gt;장기 중단 시 구독&amp;middot;슬롯 제거 후 재구독&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;적용 성능&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구독자 인덱스 사전 구축&lt;/li&gt;
&lt;li&gt;초기 스냅샷 병렬화&lt;/li&gt;
&lt;li&gt;파티셔닝 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;지연 해석&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 지연+적용 시간의 합&lt;/li&gt;
&lt;li&gt;인덱스 부재&amp;middot;제약 충돌&amp;middot;무거운 트리거 점검&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-monitor&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;11. 모니터링과 장애 대응&lt;/h2&gt;
&lt;div class=&quot;pg15-grid&quot;&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;필수 지표&lt;/h3&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;SELECT subname, status, latest_end_time, last_error FROM pg_stat_subscription;
SELECT slot_name, active, restart_lsn FROM pg_replication_slots;
SELECT application_name, state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;경보 기준&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;슬롯 비활성 10분 이상&lt;/li&gt;
&lt;li&gt;status 비정상 또는 last_error 존재&lt;/li&gt;
&lt;li&gt;WAL 디스크 사용량 80% 이상&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-tailscale&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;12. Tailscale 네트워킹&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tailscale을 사용하면 100 대역 사설 IP로 안전하게 통신합니다.&lt;/p&gt;
&lt;pre class=&quot;pg15-code pgsql&quot;&gt;&lt;code&gt;host    replication    replicator    100.64.0.0/10    md5
CREATE SUBSCRIPTION fems_sub
  CONNECTION 'host=100.64.0.10 port=5432 dbname=fems user=replicator password=***'
  PUBLICATION fems_pub;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;pg15-note&quot;&gt;ACL과 비밀번호 정책, OS 방화벽을 함께 운영합니다.&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-security&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;13. 보안 베스트프랙티스&lt;/h2&gt;
&lt;ul class=&quot;pg15-card&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복제 전용 사용자 최소 권한&lt;/li&gt;
&lt;li&gt;TLS 적용&lt;/li&gt;
&lt;li&gt;비밀은 환경 변수&amp;middot;비밀 저장소 사용&lt;/li&gt;
&lt;li&gt;로그에 비밀번호 노출 금지&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-proscons&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;14. 장단점과 해결책&lt;/h2&gt;
&lt;div class=&quot;pg15-grid&quot; style=&quot;grid-template-columns: 1fr 1fr;&quot;&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;선택적 복제&lt;/li&gt;
&lt;li&gt;이기종 버전&amp;middot;플랫폼&lt;/li&gt;
&lt;li&gt;다중 게시자 집계&lt;/li&gt;
&lt;li&gt;CDC 파이프라인 입력 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;h3 class=&quot;pg15-h3&quot; data-ke-size=&quot;size23&quot;&gt;단점&amp;middot;대응&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DDL 미복제 &amp;rarr; 마이그레이션 후 REFRESH&lt;/li&gt;
&lt;li&gt;시퀀스 불일치 &amp;rarr; setval() 보정&lt;/li&gt;
&lt;li&gt;슬롯로 WAL 누적 &amp;rarr; 모니터링&amp;middot;타임아웃&lt;/li&gt;
&lt;li&gt;PK 부재 &amp;rarr; PK 설계 또는 REPLICA IDENTITY FULL&lt;/li&gt;
&lt;li&gt;다중 쓰기 충돌 &amp;rarr; 단일 쓰기 원칙&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-checklist&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;15. 배포 체크리스트&lt;/h2&gt;
&lt;ul class=&quot;pg15-card&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;스키마&lt;/span&gt; 게시자&amp;middot;구독자 DDL 일치&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;계정&lt;/span&gt; 최소 권한&amp;middot;정책&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;네트워크&lt;/span&gt; Tailscale/방화벽/pg_hba&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;파라미터&lt;/span&gt; senders&amp;middot;slots&amp;middot;workers 확보&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;초기화&lt;/span&gt; 데이터 양에 맞는 전략&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;모니터링&lt;/span&gt; 상태&amp;middot;슬롯&amp;middot;WAL 알림&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;pg15-badge&quot;&gt;복구&lt;/span&gt; DROP&amp;middot;재구독 절차 문서화&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;pg15-conclusion&quot; class=&quot;pg15-section pg15-anchor&quot;&gt;
&lt;h2 class=&quot;pg15-h2&quot; data-ke-size=&quot;size26&quot;&gt;16. 마무리&lt;/h2&gt;
&lt;div class=&quot;pg15-card&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리 복제는 동기화 기능을 넘어 데이터 흐름 설계입니다. 개념과 옵션, 초기 로딩&amp;middot;재동기화, 트리거&amp;middot;모니터링, 네트워크 구성까지 운영에 필요한 내용을 담았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현장 문제와 해결 과정을 기록하면 다음 선택이 더 빠르고 안전해집니다. 더 좋은 방법이 있다면 계속 보완하겠습니다.&lt;/p&gt;
&lt;div class=&quot;pg15-note&quot;&gt;설정과 DDL, 스크립트를 버전 관리하고 지연&amp;middot;슬롯 상태 알림을 자동화하세요.&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;footer style=&quot;margin-top: 38px; text-align: center; color: #5c6677; font-size: .95rem;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PostgreSQL 논리 복제 실무 가이드&lt;/b&gt; &amp;middot; PostgreSQL 15 기준&lt;/p&gt;
&lt;/footer&gt;&lt;/article&gt;</description>
      <category>DEVELOPMENT</category>
      <category>FEMS</category>
      <category>LogicalReplication</category>
      <category>PostgreSQL</category>
      <category>PostgreSQL실무</category>
      <category>Replication설정</category>
      <category>Tailscale</category>
      <category>공장데이터</category>
      <category>논리복제</category>
      <category>데이터동기화</category>
      <category>실시간게더링</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/555</guid>
      <comments>https://odinbox.tistory.com/555#entry555comment</comments>
      <pubDate>Sat, 18 Oct 2025 20:32:24 +0900</pubDate>
    </item>
    <item>
      <title>CSS보다 어려운 건 한가위 인사 - 스킨 2.0 완성기</title>
      <link>https://odinbox.tistory.com/554</link>
      <description>&lt;div&gt;
&lt;style&gt;
.tp{--ink:#0f1331;--ink2:#4b5570;--bg:#fcfdff;--card:#fff;--bd:#e7ecff;--g1:#66e3ff;--g2:#a68cff;--acc:#35f0b8;--r:18px;--sh:0 14px 40px rgba(96,120,255,.18);color:var(--ink);background:var(--bg);line-height:1.8;font-size:16px;position:relative;isolation:isolate;z-index:2;margin-bottom:48px;contain:paint}
@media (prefers-color-scheme:dark){.tp{--ink:#eaf0ff;--ink2:#cfd7f0;--bg:#0b0f17;--card:rgba(255,255,255,.06);--bd:rgba(255,255,255,.14);--sh:0 18px 46px rgba(0,0,0,.55)}}
.tp *{box-sizing:border-box}
.tp a{color:#5b72ff;text-decoration:none}
.tp a:hover{opacity:.9}
.tp img{max-width:100%;height:auto;border-radius:14px}
.tp code,.tp pre{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}
.tp .hero{border-radius:24px;margin:0 0 12px;padding:clamp(20px,3vw,36px);background:radial-gradient(900px 520px at -10% -10%,rgba(124,148,255,.26),transparent 60%),radial-gradient(900px 520px at 110% -10%,rgba(166,140,255,.24),transparent 60%),linear-gradient(180deg,#f3f7ff,#ffffff);box-shadow:var(--sh)}
.tp .hero h1{margin:0 0 6px;font-size:clamp(28px,4.6vw,40px);letter-spacing:-.02em}
.tp .subtitle{color:var(--ink2);margin:2px 0 12px}
.tp .meta{display:flex;flex-wrap:wrap;gap:8px;font-size:13px;color:var(--ink2)}
.tp .chip{padding:7px 12px;border:1px solid var(--bd);border-radius:999px;background:#fff}
.tp .toc-top{position:sticky;top:0;z-index:5;background:color-mix(in oklab,var(--bg),#fff 70%);border:1px solid var(--bd);border-radius:16px;margin:12px 0;padding:10px;backdrop-filter:saturate(140%) blur(8px);box-shadow:var(--sh)}
.tp .toc-wrap{display:flex;gap:8px;align-items:center;overflow:auto;scrollbar-width:none;white-space:nowrap}
.tp .toc-wrap::-webkit-scrollbar{display:none}
.tp .toc-link{display:inline-flex;align-items:center;padding:8px 12px;border-radius:12px;border:1px solid var(--bd);background:#fff;color:var(--ink2)}
.tp .toc-link:hover{background:#f2f6ff}
.tp .toc-link.active{background:linear-gradient(90deg,var(--g1),var(--g2));color:#fff;border-color:transparent}
.tp .infobar{display:flex;align-items:center;gap:10px;border:1px solid var(--bd);border-radius:14px;padding:10px 12px;background:#fff;box-shadow:var(--sh);overflow:auto;scrollbar-width:none;white-space:nowrap}
.tp .infobar::-webkit-scrollbar{display:none}
.tp .i-item{display:inline-flex;align-items:center;gap:8px;padding:8px 12px;border:1px solid var(--bd);border-radius:999px;background:#fff;color:var(--ink2)}
.tp .tag{display:inline-flex;align-items:center;gap:6px;padding:7px 10px;border:1px dashed var(--bd);border-radius:999px;background:#fff}
.tp .tag:before{content:&quot;#&quot;;opacity:.7}
.tp .content{display:grid;gap:18px}
.tp .card{background:var(--card);border:1px solid var(--bd);border-radius:var(--r);padding:clamp(16px,2.2vw,22px);box-shadow:var(--sh)}
.tp h2{font-size:clamp(20px,3.2vw,26px);margin:22px 0 10px;scroll-margin-top:88px}
.tp h3{font-size:clamp(18px,2.6vw,22px);margin:18px 0 6px;scroll-margin-top:88px}
.tp p{margin:.2em 0 1em}
.tp .lead{font-size:1.06rem;color:var(--ink2)}
.tp .callout{border-left:4px solid #5b72ff;background:#f4f7ff;padding:14px 16px;border-radius:12px;margin:6px 0}
.tp pre{background:#0a1222;color:#e2e8f0;padding:14px 16px;border-radius:12px;overflow:auto}
.tp table{width:100%;border-collapse:collapse;font-size:.94rem;display:block;overflow:auto}
.tp th,.tp td{border:1px solid var(--bd);padding:10px 12px}
.tp th{text-align:left;background:#f5f7ff}
.tp .grid{display:grid;gap:12px}
.tp .grid.cols-3{grid-template-columns:repeat(3,1fr)}
@media(max-width:780px){.tp .grid.cols-3{grid-template-columns:1fr}}
.tp .yt{position:relative;width:100%;padding-top:56.25%;border-radius:16px;overflow:hidden}
.tp .yt iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
@keyframes up{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.tp [data-reveal]{opacity:0;transform:translateY(10px)}
.tp [data-reveal].on{animation:up .55s ease-out forwards}
.tp .card:last-of-type{margin-bottom:12px}
.tp::after{content:&quot;&quot;;display:block;height:160px}
.tp + *{margin-top:24px !important;clear:both}
.tp ~ .container_postbtn,.tp ~ .another_category,.tp ~ .post_ccl,.tp ~ .postbtn_wrap,.tp ~ .entry-ccl,.tp ~ .tt_more_related,.tp ~ .tags,.tp ~ .post-share,.tp ~ .main_promo,.tp ~ [class*=&quot;donat&quot;],.tp ~ [class*=&quot;sponsor&quot;],.tp ~ [class*=&quot;coffee&quot;]{margin-top:32px !important;clear:both;position:relative;z-index:1}
&lt;/style&gt;
&lt;/div&gt;
&lt;article class=&quot;tp&quot;&gt;
&lt;section class=&quot;hero&quot; data-reveal=&quot;&quot;&gt;
&lt;h1&gt;티스토리 스킨 전면 개편 + 2025 추석 인사&lt;/h1&gt;
&lt;p class=&quot;subtitle&quot; data-ke-size=&quot;size16&quot;&gt;검색 모달&amp;middot;포털형 메인 화면&amp;middot;카테고리&amp;middot;댓글 디자인까지, 블로그 2.0 업데이트 보고서&lt;/p&gt;
&lt;div class=&quot;meta&quot;&gt;&lt;span class=&quot;chip&quot;&gt;작성자: &lt;span&gt;최영환&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;chip&quot;&gt;작성일: &lt;time datetime=&quot;2025-10-08&quot;&gt;2025-10-08&lt;/time&gt;&lt;/span&gt; &lt;span class=&quot;chip&quot;&gt;카테고리: 스킨개편 &amp;middot; 공지&lt;/span&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;!-- 대표 썸네일(히어로 아래) --&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JAwoM/btsQ4Wk0IWg/jwd55JM35ckFPy9FiOtlrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JAwoM/btsQ4Wk0IWg/jwd55JM35ckFPy9FiOtlrK/img.png&quot; data-alt=&quot;글 상단 부분 대표 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JAwoM/btsQ4Wk0IWg/jwd55JM35ckFPy9FiOtlrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJAwoM%2FbtsQ4Wk0IWg%2Fjwd55JM35ckFPy9FiOtlrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;글 상단 부분 대표 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;div id=&quot;tpTOC&quot; class=&quot;toc-top&quot;&gt;
&lt;div id=&quot;tpTOCWrap&quot; class=&quot;toc-wrap&quot;&gt;&lt;a class=&quot;toc-link&quot; href=&quot;#intro&quot;&gt;서론&lt;/a&gt; &lt;a class=&quot;toc-link&quot; href=&quot;#search&quot;&gt;검색창 리뉴얼&lt;/a&gt; &lt;a class=&quot;toc-link&quot; href=&quot;#home&quot;&gt;메인 화면 개편&lt;/a&gt; &lt;a class=&quot;toc-link&quot; href=&quot;#category&quot;&gt;카테고리 글 목록&lt;/a&gt; &lt;a class=&quot;toc-link&quot; href=&quot;#comments&quot;&gt;댓글 디자인&lt;/a&gt; &lt;a class=&quot;toc-link&quot; href=&quot;#benefit&quot;&gt;개선 효과&lt;/a&gt; &lt;a class=&quot;toc-link&quot; href=&quot;#outro&quot;&gt;마무리&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;infobar&quot; aria-label=&quot;글 정보 및 태그&quot;&gt;&lt;span class=&quot;i-item&quot;&gt;읽는 시간: 약 3~4분&lt;/span&gt; &lt;span class=&quot;i-item&quot;&gt;업데이트: &lt;time datetime=&quot;2025-10-08&quot;&gt;2025-10-08&lt;/time&gt;&lt;/span&gt; &lt;span class=&quot;tag&quot;&gt;티스토리스킨&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;블로그검색창&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;카테고리글목록&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;포털형메인화면&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;UX개선&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;스킨개편&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;개발자블로그&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;댓글디자인&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;2025추석&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;추석인사&lt;/span&gt;&lt;/div&gt;
&lt;main class=&quot;content&quot;&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;intro&quot; data-ke-size=&quot;size26&quot;&gt;서론&lt;/h2&gt;
&lt;p class=&quot;lead&quot; data-ke-size=&quot;size16&quot;&gt;추석 연휴에 블로그의 집안 단장을 마쳤습니다. 개발자 모드로 요약하면 UI/UX 리팩터링, 탐색 플로우 개선, 첫 인상 최적화. 이번 글에서는 티스토리 스킨 개편 핵심 포인트를 빠르게 소개합니다.&lt;/p&gt;
&lt;div class=&quot;callout&quot;&gt;목표: 검색 가시성 강화 &amp;middot; 첫 화면 탐색성 향상 &amp;middot; 카테고리&amp;middot;댓글 가독성 업그레이드&lt;/div&gt;
&lt;/section&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;search&quot; data-ke-size=&quot;size26&quot;&gt;검색창 리뉴얼: 상단 우측 버튼 &amp;rarr; 모달&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;/li&gt;
&lt;li&gt;ESC/모달 외 클릭으로 즉시 닫기, 모바일 대응&lt;/li&gt;
&lt;li&gt;라이트&amp;middot;다크 대응, 포커스 유지로 접근성 강화&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1035&quot; data-origin-height=&quot;917&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bamgLR/btsQ3iJv72D/LjnLYgPj3zqkUShTHq7Ggk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bamgLR/btsQ3iJv72D/LjnLYgPj3zqkUShTHq7Ggk/img.png&quot; data-alt=&quot;검색&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bamgLR/btsQ3iJv72D/LjnLYgPj3zqkUShTHq7Ggk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbamgLR%2FbtsQ3iJv72D%2FLjnLYgPj3zqkUShTHq7Ggk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1035&quot; height=&quot;917&quot; data-origin-width=&quot;1035&quot; data-origin-height=&quot;917&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;검색&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;home&quot; data-ke-size=&quot;size26&quot;&gt;메인 화면 개편: 포털형 카드 UI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 페이지를 카드형 포털 레이아웃으로 재배치했습니다. 썸네일&amp;middot;제목&amp;middot;요약이 보이는 카드들이 섹션별로 구성되어 첫 3초의 인상을 확 끌어올립니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;섹션별 최신&amp;middot;인기&amp;middot;테마 바로 접근&lt;/li&gt;
&lt;li&gt;반응형 그리드로 시선 흐름 안정화&lt;/li&gt;
&lt;li&gt;가벼운 인터랙션으로 체류 시간 개선 기대&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;1035&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tvNiy/btsQ31G9RkG/8Sz7FinDKeDjTVwCNkx0SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tvNiy/btsQ31G9RkG/8Sz7FinDKeDjTVwCNkx0SK/img.png&quot; data-alt=&quot;홈화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tvNiy/btsQ31G9RkG/8Sz7FinDKeDjTVwCNkx0SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtvNiy%2FbtsQ31G9RkG%2F8Sz7FinDKeDjTVwCNkx0SK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;436&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;1035&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;홈화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;category&quot; data-ke-size=&quot;size26&quot;&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;/li&gt;
&lt;li&gt;요약문으로 난이도&amp;middot;의도 파악 용이&lt;/li&gt;
&lt;li&gt;뉴스피드처럼 자연스러운 스캐닝 경험&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdprA4/btsQ2jouifo/o2m26FOk6dkYqsEy7w2uDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdprA4/btsQ2jouifo/o2m26FOk6dkYqsEy7w2uDK/img.png&quot; data-alt=&quot;카테고리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdprA4/btsQ2jouifo/o2m26FOk6dkYqsEy7w2uDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdprA4%2FbtsQ2jouifo%2Fo2m26FOk6dkYqsEy7w2uDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;546&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;카테고리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;comments&quot; data-ke-size=&quot;size26&quot;&gt;댓글 디자인: 읽기 쉬운 스레드형으로 리프레시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;댓글 영역도 새로 손봤습니다. 가독성 중심의 스레드형에 아바타, 작성자명 대비, 시간&amp;middot;버튼 배치를 재정렬했습니다. 답글은 들여쓰기로 레벨을 구분하고, 모바일에서는 버튼을 아이콘으로 축소해 조작을 단순화했습니다.&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;middot;입력 스트레스 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn8Z3i/btsQ4mdfSF9/xifJWYTcKgE0sY3ckudIn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn8Z3i/btsQ4mdfSF9/xifJWYTcKgE0sY3ckudIn1/img.png&quot; data-alt=&quot;댓글디자인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn8Z3i/btsQ4mdfSF9/xifJWYTcKgE0sY3ckudIn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn8Z3i%2FbtsQ4mdfSF9%2FxifJWYTcKgE0sY3ckudIn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;777&quot; height=&quot;195&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;댓글디자인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;benefit&quot; 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;&lt;b&gt;검색성&lt;/b&gt;: 모달 검색으로 접근성&amp;uarr;, 최신글 노출 동시 강화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;발견성&lt;/b&gt;: 포털형 메인으로 다양한 글을 한눈에 탐색&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가독성&lt;/b&gt;: 카테고리&amp;middot;댓글 UI 개선으로 체류&amp;middot;참여도 향상 기대&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section class=&quot;card&quot; data-reveal=&quot;&quot;&gt;
&lt;h2 id=&quot;outro&quot; data-ke-size=&quot;size26&quot;&gt;마무리 &amp;middot; 2025 추석 인사&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풍성한 한가위 보내셨나요? 여러분의 행복이 &lt;code&gt;while(true)&lt;/code&gt;처럼 이어지고, 일상의 버그들은 한 번에 &lt;code&gt;fix()&lt;/code&gt; 되길 바랍니다. 새 스킨과 함께 이 블로그는 기술 포스팅, 일상 기록, 커뮤니티 소통을 꾸준히 이어가겠습니다. 방문해 주셔서 감사합니다. 보름달처럼 꽉 찬 한 해 되세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백은 언제든 환영입니다. 작은 의견이 다음 릴리즈의 핵심 기능이 될 수 있어요.&lt;/p&gt;
&lt;/section&gt;
&lt;/main&gt;&lt;/article&gt;
&lt;script&gt;
(function(){
  var root=document.currentScript.previousElementSibling;
  if(!(root&amp;&amp;root.classList&amp;&amp;root.classList.contains('tp'))){root=document.querySelector('.tp');}
  if(!root) return;
  var rev=root.querySelectorAll('[data-reveal]');
  var io2=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('on');io2.unobserve(e.target);}})},{threshold:.12});
  rev.forEach(function(el){io2.observe(el)});
  var links=[].slice.call(root.querySelectorAll('#tpTOC .toc-link'));
  var map={}; links.forEach(function(a){var id=(a.getAttribute('href')||'').replace('#',''); if(id) map[id]=a;});
  var heads=[].slice.call(root.querySelectorAll('h2,h3')).filter(function(h){return h.id&amp;&amp;map[h.id];});
  var io=new IntersectionObserver(function(ents){
    ents.forEach(function(ent){
      if(ent.isIntersecting){
        links.forEach(function(l){l.classList.remove('active')});
        var cur=map[ent.target.id]; if(cur) cur.classList.add('active');
      }
    });
  },{rootMargin:'-55% 0px -40% 0px',threshold:0.01});
  heads.forEach(function(h){io.observe(h)});
  document.addEventListener('click',function(e){
    var a=e.target.closest('.toc-link'); if(!a) return;
    var id=a.getAttribute('href'); if(!id||id.charAt(0)!=='#') return;
    var t=root.querySelector(id); if(!t) return;
    e.preventDefault(); t.scrollIntoView({behavior:'smooth',block:'start'});
    history.replaceState(null,'',id);
  });
})();
&lt;/script&gt;</description>
      <category>NOTICE</category>
      <category>UX개선</category>
      <category>개발자블로그</category>
      <category>검색창</category>
      <category>댓글디자인</category>
      <category>명절</category>
      <category>블로그리뉴얼</category>
      <category>스킨</category>
      <category>연휴</category>
      <category>추석인사</category>
      <category>카테고리목록</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/554</guid>
      <comments>https://odinbox.tistory.com/554#entry554comment</comments>
      <pubDate>Wed, 8 Oct 2025 12:49:25 +0900</pubDate>
    </item>
    <item>
      <title>USB와 Thunderbolt 비교, 진화 과정부터 선택 가이드까지 한 번에 이해하기</title>
      <link>https://odinbox.tistory.com/553</link>
      <description>&lt;article lang=&quot;ko&quot;&gt;&lt;!-- SEO --&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;USB와 Thunderbolt의 세대별 진화, 속도와 전력, 영상 출력, 확장성, 호환성 차이를 한눈에 비교하고, 상황별 선택 가이드까지 정리한 종합 안내서&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;font-weight: normal; position: relative; line-height: 40px; background: #007CBA; border: 1px solid #fff; padding: 10px; color: white; border-radius: 0 10px 0 10px; box-shadow: inset 0 0 5px rgba(53,86,129, 0.5); font-family: 'Muli', sans-serif; border-style: solid; border-width: 0px  0px  1px 15px; border-color: #232323; background-color: #007cba;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;USB와 Thunderbolt :: 이 글 하나면 정리할 수 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJcHjd/btsQ14kv6Zn/WzmH8aSmA4c8j4nFLkOOJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJcHjd/btsQ14kv6Zn/WzmH8aSmA4c8j4nFLkOOJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJcHjd/btsQ14kv6Zn/WzmH8aSmA4c8j4nFLkOOJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJcHjd%2FbtsQ14kv6Zn%2FWzmH8aSmA4c8j4nFLkOOJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: 'Noto Sans Light';&quot;&gt;스마트폰 충전, 외장 SSD, 4K 또는 8K 모니터, 도킹 스테이션까지 이제는 한 포트로 해결합니다. 그 중심에는 USB와 Thunderbolt 표준의 꾸준한 진화가 있습니다. 이 글은 USB 1.0부터 USB4, Thunderbolt 1부터 4까지의 발전 과정을 하나의 흐름으로 설명하고, 전송속도, 전력, 영상, 확장성, 호환성 관점에서 차이를 분석합니다. 마지막에는 용도별 선택 가이드로 구매와 구축 판단을 돕습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-style: solid; font-weight: bold; border-width: 1px  1px  1px 5px; border-color: #707070; background-color: #fff; padding: 10px;&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	$(&quot;#toc&quot;).toc( {content: &quot;.tt_article_useless_p_margin&quot;, headings: &quot;h1,h2,h3,h4&quot; , top: -90, isBlink : true, blinkColor : '#21B9DE' } ) });
&lt;/script&gt;
&lt;/div&gt;
&lt;!-- 2) 세대별 기술분석 --&gt;
&lt;section id=&quot;generational-analysis&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;USB &amp;amp; 썬더볼트&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;세대별 기술분석&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB의 출발점인 USB 1.x는 다양한 직렬, 병렬 포트를 하나로 통합하고 플러그 앤 플레이, 핫스왑을 표준화하려는 요구에서 탄생했습니다. 1.5 Mbps와 12 Mbps 속도, 5V 버스 전원으로 소형 주변기기를 외부 어댑터 없이 구동할 수 있었고, Type-A(호스트), Type-B(장치) 구분이 보급을 이끌었습니다. 1998년 1.1 개정으로 안정성이 올라가며 본격 대중화가 시작됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;대용량 데이터와 휴대기기 확산에 맞춰 USB 2.0은 480 Mbps로 속도를 끌어올렸습니다. 플래시 드라이브와 외장 HDD가 일상화되었고, 5V 0.5A(이후 BC 1.2로 최대 1.5A) 전력 공급이 스마트폰 충전의 표준으로 자리 잡았습니다. 소형 연결은 Mini-USB, 이어서 Micro-USB가 주도하면서 휴대기기 생태계가 USB 중심으로 재편됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;고해상도 멀티미디어와 SSD 등장으로 병목이 커지자 USB 3.0은 5 Gbps SuperSpeed와 전이중 구조로 응답했습니다. 송신과 수신을 동시에 처리하고 UASP로 대용량 파일 처리 효율을 끌어올렸으며, 0.9A 버스 전원으로 버스파워 장치 운용 여지가 커졌습니다. 파란색 인서트 Type-A/B(9핀), Micro-B(SS)가 이 세대의 상징처럼 쓰였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB 3.1은 인코딩 개선으로 10Gbps에 도달했지만, 더 큰 전환점은 USB Type-C였습니다. 위아래 구분 없는 리버서블, 소형, 내구성 높은 설계에 더해, 한 포트에서 데이터, 영상(DisplayPort Alt Mode), 전원(USB Power Delivery)을 통합 처리합니다. 최대 100W 충전이 가능해지며 노트북 충전이 USB-C 중심으로 이동했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB 3.2는 새로운 신호 대신 USB-C 내부의 두 레인을 병렬로 묶어 최대 20 Gbps(Gen2x2)를 달성했습니다. 고성능 외장 NVMe SSD에서 체감 이점이 컸지만, 호스트, 장치, 케이블 모두가 동일 모드를 지원해야 하고 명칭 체계가 복잡해 사용자 혼선도 있었습니다. 그럼에도 USB-C 하나로 더 빠르게, 더 많이 연결한다는 방향은 더욱 공고해졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB4는 Thunderbolt 3 기술을 흡수해 최대 40 Gbps에서 USB 3.x, PCI Express, DisplayPort를 터널링 합니다. 단일 USB-C 포트로 고속 스토리지, 고해상도 디스플레이, 도킹 확장을 동시에 처리하기 쉬워졌고, 동시대의 USB PD 3.1과 결합하면 최대 240W 전력 전달 생태계가 열렸습니다. 구현에 따라 Thunderbolt 3 호환이 가능한 제품이 많아지며 사실상 경계가 크게 좁혀졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Thunderbolt는 전문가 워크플로를 겨냥해 별도의 궤적으로 발전했습니다. Thunderbolt 1은 Mini DisplayPort 형태에 10 Gbps 듀얼 채널(총 20 Gbps)로 PCIe 데이터와 DisplayPort 영상을 한 케이블로 처리했고, 최대 6대 데이지체인을 지원했습니다. Thunderbolt 2는 두 채널을 하나로 묶어 단일 20 Gbps 스트림을 구성, 4K 작업 흐름을 안정화했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Thunderbolt 3는 USB-C 채택과 함께 40Gbps, PCIe 3.0 x4 + DP 1.2, USB 3.1 호환 모드, PD 최대 100W를 한 포트에 통합했습니다. eGPU, NVMe RAID, 듀얼 4K 또는 단일 5K 구성까지 노트북 한 포트로 실현하면서 사실상 USB-C의 최상위 모드가 되었습니다. Thunderbolt 4는 속도는 동일하지만 듀얼 4K 또는 단일 8K, PCIe 32 Gbps 보장, 정식 Thunderbolt 허브(멀티 포트 분기), 강화된 보안 같은 최소 요구사항을 의무화해 일관성과 안정성을 크게 높였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; USB4와의 폭넓은 호환성도 유지됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;!-- 3) 핵심 차이 --&gt;
&lt;section id=&quot;differences&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;USB와 Thunderbolt의 핵심 차이(논리적 비교)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;철학과 목표&lt;/b&gt; : USB는 보급형, 범용, 저비용, 광호환을 지향합니다. Thunderbolt는 고성능, 저지연, 강력한 확장을 지향합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;프로토콜과 대역폭 활용&lt;/b&gt; : USB는 USB 패킷과 Alt Mode 중심, Thunderbolt는 PCIe와 DisplayPort를 동시 터널링합니다. 동일 40Gbps라도 NVMe, eGPU 같은 작업에서 Thunderbolt가 유리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;영상 출력&lt;/b&gt; : USB-C의 DP Alt Mode로 단일 4K는 충분합니다. 듀얼 4K, 8K, 고주사율, 고컬러뎁스 구성은 Thunderbolt가 일관성과 여유가 큽니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;전력 전달&lt;/b&gt; : USB PD는 100W, 일부 240W까지 확장됩니다. Thunderbolt 포트도 USB-C 기반이므로 PD를 활용하며, 인증 기기는 고부하에서도 전력, 대역폭 관리가 일관적인 편입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;확장 토폴로지&lt;/b&gt; : USB는 허브 중심(스타형), Thunderbolt는 데이지체인에 더해 Thunderbolt 4부터 허브 분기를 지원합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;케이블과 길이 : 고속일수록 길이에 민감합니다. USB 3.2 Gen2x2, USB4, TB3/4 모두 케이블 인증, 길이, 액티브/패시브 여부가 성능을 좌우합니다. Thunderbolt는 인증 체계가 엄격합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;비용과 생태계&lt;/b&gt; : USB는 저비용, 광범위 보급입니다. Thunderbolt는 컨트롤러와 독 비용이 높지만, 도킹과 프로 워크플로에서 안정성과 확장성이 뛰어납니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;호환성&lt;/b&gt; : TB3/4 포트는 USB 장치를 수용합니다. 반대로 USB 전용 포트는 TB 장치를 인식하지 못합니다. USB4는 TB3 호환 구현이 많아 경계가 좁혀졌습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;!-- 4) 한눈에 보는 USB vs Thunderbolt (Styled Table) --&gt;
&lt;section id=&quot;comparison&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;한눈에 보는 USB vs Thunderbolt&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div class=&quot;meta&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;한눈에 파악할 수 있도록 핵심 포인트를 빠르게 비교하세요.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;table-wrap&quot; role=&quot;region&quot; aria-label=&quot;USB와 Thunderbolt 비교표&quot;&gt;
&lt;div class=&quot;table-scroll&quot;&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;구분&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Thunderbolt&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;첫 도입, 목표&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;1996, 주변기기 포트 통합, 플러그앤플레이, 핫스왑 표준화&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2011, 전문가 워크플로(스토리지, 영상)용 초고속 단일 케이블&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;최신 세대&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB4, 20/40Gbps, USB-C 전용&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Thunderbolt 4, 40Gbps, USB-C&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;대역폭, 방식&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;480Mbps(2.0) &amp;rarr; 5/10/20Gbps(3.x) &amp;rarr; 20/40Gbps(USB4)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;20Gbps(TB1/2) &amp;rarr; 40Gbps(TB3/4), PCIe + DisplayPort 동시 터널링&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;영상 출력&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB-C의 DP Alt Mode, 구현 의존, 단일 4K 중심&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;DP 터널링 기본, 듀얼 4K 또는 단일 8K까지 안정적 구성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;전력 공급&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB PD 최대 100W, PD 3.1 환경 최대 240W&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;버스전원 10~15W, USB PD 최대 100W(제품 구현)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;확장 토폴로지&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;허브 중심(스타형), 데이지체인 불가&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;데이지체인(최대 6대), TB4 허브 분기 지원&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;호환성&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;세대 간 하위호환 광범위, USB4는 TB3 호환 가능(옵션)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;TB3/4 포트는 USB 장치 수용, USB 전용 포트는 TB 장치 미지원&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;케이블, 길이&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Gen/레인/길이/인증에 따라 성능 좌우, 특히 Gen2x2, USB4&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;40Gbps 장거리에는 액티브 케이블 요구, 인증 체계 엄격&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;비용, 생태계&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;저비용, 광범위 보급&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;고급형, 전문 생태계, 컨트롤러/독 가격대 높음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;대표 용도&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;충전, 일반 주변기기, 외장 SSD, 단일 4K 모니터&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;eGPU, 초고속 NVMe RAID, 듀얼 4K 또는 8K, 전문 영상/오디오&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;!-- 5) 기술 진화도(타임라인) --&gt;
&lt;section id=&quot;timeline&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;기술 진화도(타임라인)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;1996&quot;&gt;1996&lt;/time&gt; USB 1.0, 1.5/12Mbps&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;1998&quot;&gt;1998&lt;/time&gt; USB 1.1, 대중화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2000&quot;&gt;2000&lt;/time&gt; USB 2.0, 480Mbps, Mini/Micro-USB 확산&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2008&quot;&gt;2008&lt;/time&gt; USB 3.0, 5Gbps, 전이중, UASP&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2011&quot;&gt;2011&lt;/time&gt; Thunderbolt 1, 20Gbps, Mini DP, 데이지체인&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2013&quot;&gt;2013&lt;/time&gt; USB 3.1, 10Gbps, USB-C, DP Alt Mode, USB PD, Thunderbolt 2, 20Gbps&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2015&quot;&gt;2015&lt;/time&gt; Thunderbolt 3, 40Gbps, USB-C, PCIe 3.0 x4 + DP 1.2, PD 100W&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2017&quot;&gt;2017&lt;/time&gt; USB 3.2, 최대 20Gbps, 멀티레인 Gen2x2&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2019&quot;&gt;2019&lt;/time&gt; USB4, 20/40Gbps, TB3 기술 통합, 다중 프로토콜 터널링&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;time datetime=&quot;2020&quot;&gt;2020&lt;/time&gt; Thunderbolt 4, 40Gbps, 듀얼 4K 또는 8K, TB 허브, 강화된 최소요건&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;!-- 6) 상황별 선택 가이드 --&gt;
&lt;section id=&quot;guide&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상황별 선택 가이드&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;일반 사용&lt;/b&gt; : 스마트폰 충전, 백업, 주변기기 연결, 단일 4K 모니터는 USB-C(USB 3.1/3.2 이상)와 PD 충전기로 충분합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;대용량/고속 저장&lt;/b&gt; : 외장 NVMe SSD는 10Gbps 이상 권장, USB 3.2 Gen2x2(20Gbps) 또는 Thunderbolt 3/4(40Gbps) 고려.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;멀티 디스플레이&lt;/b&gt; : 단일 4K는 USB-C DP Alt Mode로 무난, 듀얼 4K 또는 8K, 고주사율은 Thunderbolt 3/4 또는 USB4가 안정적.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;eGPU, 전문 영상/오디오&lt;/b&gt; : PCIe급 대역폭이 필요한 워크플로는 Thunderbolt 3/4가 사실상 표준입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;노트북/모니터 전원&lt;/b&gt; : 65~100W는 USB PD로 충분, 고출력 장비는 PD 3.1(최대 240W) 지원 여부 확인.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;케이블 체크&lt;/b&gt; : 표기 대역(20/40Gbps), 길이, 액티브/패시브, PD 등급을 반드시 확인, 인증 케이블 사용이 성능과 안정성을 좌우합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;!-- 7) 마무리 --&gt;
&lt;section id=&quot;outro&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;USB는 범용성과 저비용, 광호환을 무기로 일상 연결의 표준이 되었고, Thunderbolt는 PCIe와 DisplayPort 터널링, 엄격한 인증을 바탕으로 고성능, 저지연 확장을 책임져 왔습니다. USB4가 TB3 기술을 흡수하면서 두 세계는 USB-C라는 단자 아래 사실상 수렴 중입니다. 일반 용도는 USB로 충분하며, 고성능, 멀티 디스플레이, 전문 워크플로는 Thunderbolt 3/4 또는 USB4가 해답입니다. 앞으로도 USB-C 한 포트로 데이터, 영상, 전원, 확장을 아우르는 흐름은 더 강화될 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/article&gt;
&lt;div&gt;
&lt;style&gt;
    /* Readability-first table styles */
     :root {
      --bg : #ffffff;
      --text : #111827;
      --muted : #6b7280;
      --primary : #0ea5e9;
      --border : #e5e7eb;
      --row : #f9fafb;
      --row2 : #ffffff;
      --shadow : 0 1px 2px rgba(0,0,0,0.05);
      --radius : 12px;
    }
    body, table { color : var(--text); }
    section { margin : 1.25rem 0 1.75rem; }
    p { line-height : 1.7; margin : 0.6rem 0; }
    h1, h2 { line-height : 1.35; }
    h1 { font-size : 1.85rem; margin : 0 0 1rem; }
    h2 { font-size : 1.35rem; margin : 1.2rem 0 0.6rem; }
    ul { padding-left : 1.1rem; }
    ul li { margin : 0.35rem 0; }

    .table-wrap {
      margin-top : 0.8rem;
      background : var(--bg);
      border : 1px solid var(--border);
      border-radius : var(--radius);
      overflow : hidden;
      box-shadow : var(--shadow);
    }
    .table-scroll {
      overflow-x : auto;
      -webkit-overflow-scrolling : touch;
    }
    table {
      width : 100%;
      border-collapse : separate;
      border-spacing : 0;
      min-width : 760px;
    }
    thead th {
      position : sticky;
      top : 0;
      background : #f1f5f9;
      text-align : left;
      padding : 12px 14px;
      font-weight : 600;
      border-bottom : 1px solid var(--border);
      white-space : nowrap;
    }
    tbody td {
      padding : 12px 14px;
      vertical-align : top;
      border-bottom : 1px solid var(--border);
    }
    tbody tr :nth-child(odd) { background : var(--row); }
    tbody tr :nth-child(even) { background : var(--row2); }
    tbody tr :hover { background : #eef6ff; }
    .meta {
      color : var(--muted);
      font-size : 0.95rem;
      margin-top : -0.35rem;
      margin-bottom : 0.4rem;
    }
    .tag {
      display : inline-block;
      font-size : .8rem;
      color : #0369a1;
      background : #e0f2fe;
      border : 1px solid #bae6fd;
      padding : 2px 8px;
      border-radius : 999px;
      margin-right : 6px;
      margin-bottom : 6px;
    }
  &lt;/style&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>thunderbolt</category>
      <category>usb</category>
      <category>usb-c</category>
      <category>usb4</category>
      <category>고속충전</category>
      <category>도킹스테이션</category>
      <category>모니터출력</category>
      <category>외장SSD</category>
      <category>전송속도</category>
      <category>하드웨어가이드</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/553</guid>
      <comments>https://odinbox.tistory.com/553#entry553comment</comments>
      <pubDate>Sat, 4 Oct 2025 10:34:36 +0900</pubDate>
    </item>
    <item>
      <title>카카오 if(kakao)25 후기</title>
      <link>https://odinbox.tistory.com/552</link>
      <description>&lt;div&gt;
&lt;style&gt;
  :root{
    --ink:#0f172a;           
    --ink-2:#334155;         
    --bg:#ffffff;            
    --accent:#007CBA;        
    --accent-2:#0ea5e9;      
    --line:#e9eef3;          
    --muted:#64748b;         
    --radius:14px;           
    --radius-sm:10px;
    --shadow:0 16px 38px rgba(2,14,40,.10);
    --shadow-sm:0 6px 20px rgba(2,14,40,.08);
    --shadow-hover:0 22px 48px rgba(2,14,40,.16);
    --maxw:980px;            
  }

  .devconf-article{max-width:var(--maxw);margin:0 auto;padding:8px 16px;color:var(--ink);line-height:1.75;word-break:keep-all}
  .devconf-article p{margin:1rem 0}
  .devconf-article h1,.devconf-article h2,.devconf-article h3,.devconf-article h4{
    font-family:&quot;Nanum Gothic&quot;,&quot;Noto Sans KR&quot;,system-ui,AppleSDGothicNeo,&quot;Segoe UI&quot;,sans-serif;
    color:var(--ink); 
  }
  .devconf-article h2{font-size:1.65rem;font-weight:800;margin:2.2rem 0 1rem;display:flex;align-items:center;gap:.6rem}
  .devconf-article h2::before{content:&quot;&quot;;display:inline-block;width:10px;height:10px;border-radius:3px;background:var(--accent);box-shadow:0 0 0 6px rgba(0,124,186,.12)}
  .devconf-article h3{font-size:1.35rem;font-weight:800;margin:1.6rem 0 .6rem}
  .devconf-article h4{font-size:1.12rem;font-weight:700;margin:1.2rem 0 .4rem;color:#0b3c59}

  .devconf-hero p[data-ke-size]{margin:.25rem 0}
  .devconf-hero .txc-textbox{
    position:relative;border:0;background:linear-gradient(135deg,var(--accent),#0097d1);
    color:#fff;border-radius:0 14px 0 14px;padding:16px 18px;box-shadow:inset 0 0 6px rgba(0,0,0,.15), var(--shadow-sm);
  }
  .devconf-hero .txc-textbox b{letter-spacing:.2px}
  .devconf-hero .txc-textbox::after{
    content:&quot;Developer Conference&quot;;position:absolute;right:10px;bottom:8px;font-size:.75rem;opacity:.6
  }

  .dev-card{background:var(--bg);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px 18px;margin:16px 0}
  .dev-card:hover{box-shadow:var(--shadow-hover);transition:box-shadow .25s ease}

  .devconf-article .txc-textbox:not(.devconf-hero .txc-textbox){
    border:1px solid var(--line)!important;background:#fbfdff!important;border-left:6px solid var(--accent)!important;
    border-radius:12px!important;box-shadow:var(--shadow-sm)!important;padding:14px 16px!important
  }

  .dev-toc{position:relative;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow);margin:18px 0 28px}
  .dev-toc p{margin:.2rem 0 .6rem;color:var(--muted);font-weight:700}
  .dev-toc ul#toc{list-style:none;padding:0;margin:0;display:grid;gap:.35rem}
  .dev-toc ul#toc li a{display:block;text-decoration:none;color:var(--ink-2);padding:.28rem .4rem;border-radius:10px}
  .dev-toc ul#toc li a:hover{background:#f0f9ff;color:#075985}

  .devconf-article img{max-width:100%;height:auto;border-radius:12px;box-shadow:var(--shadow-sm)}
  .devconf-article p:has([id^=&quot;_Image&quot;],[id^=&quot;_ImageGrid&quot;]){margin:1rem 0}
  .img-grid{display:grid;gap:10px}
  .devconf-article .alignCenter{display:block;margin-inline:auto}

  .dev-file{display:flex;align-items:center;gap:10px;background:#f8fbff;border:1px solid var(--line);border-radius:12px;padding:10px 12px;margin:10px 0}
  .dev-file .dev-file-ic{width:28px;height:28px;flex:0 0 28px;border-radius:6px;background:#e0f2fe;display:inline-flex;align-items:center;justify-content:center;font-weight:800;color:#0369a1}
  .dev-file a{text-decoration:none;color:#075985}
  .dev-file small{color:var(--muted)}

  .media-wrap{position:relative;width:100%;aspect-ratio:16/9;border-radius:14px;overflow:hidden;box-shadow:var(--shadow);margin:10px 0}
  .media-wrap iframe{position:absolute;inset:0;width:100%;height:100%}

  .devconf-article table{width:100%;border-collapse:collapse;border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:var(--shadow-sm);margin:14px 0}
  .devconf-article th,.devconf-article td{padding:.7rem .8rem;border-bottom:1px solid var(--line)}
  .devconf-article thead th{background:#f8fbff;text-align:left}
  pre,code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
  pre{overflow:auto;background:#0b1220;color:#e5e7eb;border-radius:12px;padding:12px 14px;box-shadow:var(--shadow-sm)}

  .dev-meta{display:flex;gap:10px;flex-wrap:wrap;color:var(--muted);font-size:.9rem;margin:.5rem 0 1.2rem}
  .dev-badge{display:inline-flex;align-items:center;gap:.4rem;background:#ecfeff;color:#0e7490;border:1px solid #99f6e4;padding:.18rem .55rem;border-radius:999px;font-size:.78rem}
  .dev-note{font-size:.95rem;color:#0b3c59;background:#f0f9ff;border:1px dashed #bae6fd;border-radius:10px;padding:10px 12px;margin:.8rem 0}

  @media (max-width: 768px){
    .devconf-article{padding:4px 12px}
    .devconf-article h2{font-size:1.4rem}
    .devconf-article h3{font-size:1.18rem}
  }

  .dev-anchor{opacity:.18;margin-left:.35rem;font-weight:600;text-decoration:none}
  .dev-anchor:hover{opacity:.5}
&lt;/style&gt;
&lt;/div&gt;
&lt;script type=&quot;application/ld+json&quot;&gt;
{
  &quot;@context&quot;:&quot;https://schema.org&quot;,
  &quot;@type&quot;:&quot;BlogPosting&quot;,
  &quot;inLanguage&quot;:&quot;ko-KR&quot;,
  &quot;headline&quot;:&quot;가능성이 일상이 될 때, if(kakao)25에서 본 AI&quot;,
  &quot;about&quot;:[&quot;if(kakao)25&quot;,&quot;Developer Conference&quot;,&quot;AI&quot;,&quot;Agent&quot;,&quot;On-device&quot;,&quot;Long Context&quot;,&quot;Multimodal&quot;],
  &quot;keywords&quot;:&quot;if(kakao)25, 카카오, 개발자 컨퍼런스, AI, 에이전트, 온디바이스, 롱컨텍스트, 멀티모달, Kanana&quot;,
  &quot;isAccessibleForFree&quot;: &quot;true&quot;,
  &quot;mainEntityOfPage&quot;:{&quot;@type&quot;:&quot;WebPage&quot;,&quot;@id&quot;:document.location.href}
}
&lt;/script&gt;
&lt;div id=&quot;devconf-article&quot; class=&quot;devconf-article&quot;&gt;
&lt;section class=&quot;devconf-hero&quot;&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개발자와 일반인 모두 즐길 수 있었던 행사&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;가능성이 일상이 될 때, if(kakao)25에서 본 AI&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nciXR/btsQR87Lz2j/qndAc5zp37gsYKi6VuxPQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nciXR/btsQR87Lz2j/qndAc5zp37gsYKi6VuxPQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nciXR/btsQR87Lz2j/qndAc5zp37gsYKi6VuxPQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnciXR%2FbtsQR87Lz2j%2FqndAc5zp37gsYKi6VuxPQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/section&gt;
&lt;div class=&quot;dev-meta&quot;&gt;&lt;span class=&quot;dev-badge&quot;&gt;if(kakao)25 현장기&lt;/span&gt; &lt;span&gt;AI &amp;middot; 에이전트 &amp;middot; 온디바이스 &amp;middot; 롱컨텍스트 &amp;middot; 멀티모달&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;dev-toc dev-card&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script&gt;
      (function(){
        if (window.jQuery){
          jQuery(function(){
            jQuery(&quot;#toc&quot;).toc({
              content: &quot;.tt_article_useless_p_margin&quot;,
              headings: &quot;h1,h2,h3,h4&quot;,
              top: -90,
              isBlink : true,
              blinkColor : '#21B9DE'
            });
          });
        }
      })();
    &lt;/script&gt;
&lt;/div&gt;
&lt;div class=&quot;tt_article_useless_p_margin&quot;&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;지난 9월 24일, 경기도 용인시에 위치한 카카오 AI캠퍼스에서 개최된 if(kakao)25 컨퍼런스에 다녀왔습니다. 올해로 7회를 맞이한 이프카카오는 카카오 그룹의 기술 비전과 성과를 공유하는 연례행사입니다. 가능성, 일상이 되다라는 슬로건 아래 인공지능 기술의 대중화를 목표로 다양한 세션과 발표가 진행되었습니다. 개발자뿐 아니라 다양한 업계 관계자들이 한자리에 모여 카카오의 AI 신기술과 서비스를 직접 체험할 수 있었던 자리였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이번 글에서는 지방에서 참가한 저의 이동 여정부터 현장 분위기, 그리고 각 세션에서 다뤄진 주요 기술 내용을 정리해 공유드립니다. 특히 카카오의 차세대 AI 모델인 카나나 시리즈, 에이전트, 온디바이스 AI최적화 등 개발자분들이 관심 가질만한 부분을 중심으로 보완설명을 덧붙였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;if(KAKAO)25&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;울산에서 서울로&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;행사가 평일 이른 아침 시작이라 전날 퇴근 후 곧바로 울산에서 서울로 이동을 했습니다. 9월 23일 퇴근 후 울산역에서 SRT를 타고 수서역에 도착 수인분당선과 2호선을 환승해 강남역 인근 숙소에 도착을 하여 다음 날 컨퍼런스에 대한 기대감을 갖고 잠에 들었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ykfza/btsQSju1EIG/Wcta6871fhsdEVC8ImmAgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ykfza/btsQSju1EIG/Wcta6871fhsdEVC8ImmAgK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ykfza/btsQSju1EIG/Wcta6871fhsdEVC8ImmAgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fykfza%2FbtsQSju1EIG%2FWcta6871fhsdEVC8ImmAgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDdFOz/btsQSipfnKx/IXQdANDpciTTmujT4NB3u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDdFOz/btsQSipfnKx/IXQdANDpciTTmujT4NB3u1/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;50&quot; style=&quot;width: 49.4186%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDdFOz/btsQSipfnKx/IXQdANDpciTTmujT4NB3u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDdFOz%2FbtsQSipfnKx%2FIXQdANDpciTTmujT4NB3u1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cce07c/btsQTSJAA4C/3moK3IItPplq1U9oN4eDC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cce07c/btsQTSJAA4C/3moK3IItPplq1U9oN4eDC0/img.png&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;13.68&quot; style=&quot;width: 13.3622%; margin-right: 10px; margin-top: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cce07c/btsQTSJAA4C/3moK3IItPplq1U9oN4eDC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcce07c%2FbtsQTSJAA4C%2F3moK3IItPplq1U9oN4eDC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQIAbd/btsQRzLBjiy/xlH52ySfOGBbWQnspGuqJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQIAbd/btsQRzLBjiy/xlH52ySfOGBbWQnspGuqJ1/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; style=&quot;width: 42.1561%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;43.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQIAbd/btsQRzLBjiy/xlH52ySfOGBbWQnspGuqJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQIAbd%2FbtsQRzLBjiy%2FxlH52ySfOGBbWQnspGuqJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/botiPK/btsQR9MivsU/WkgJbuH62n9cC9RcbXkU5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/botiPK/btsQR9MivsU/WkgJbuH62n9cC9RcbXkU5k/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; style=&quot;width: 42.1561%; margin-top: 10px;&quot; data-widthpercent=&quot;43.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/botiPK/btsQR9MivsU/WkgJbuH62n9cC9RcbXkU5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbotiPK%2FbtsQR9MivsU%2FWkgJbuH62n9cC9RcbXkU5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;당일 아침, 셔틀 탑승과 입장&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;9월 24일 아침 7시에 일어나 준비를 마쳤고 8시 10분쯤 강남역 5번 출구에 도착을 했습니다. 셔틀 탑스안내 피켓을 든 진행요원을 따라 QR코드로 탑승 확인을 했고 8시 30분 정시에 셔틀이 출발했습니다. 약 한 시간 후 용인 수지구에 위치한 카카오 AI캠퍼스에 도착을 했고 간단히 초대권 확인을 마치고 웰컴 키트를 수령했습니다. 본 행사장으로 이동을 하니 직원분들의 박수 환대가 이어졌고 극I였던 저로써는 잠시동안 공포의 시간이였고 일찍 도착하여 거의 맨 앞줄에 착석을 할 수 있었습니다. 그 이후 참가하는 분들도 많이 들어왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5RHRM/btsQTrlaInc/W2jXAqQHrRaBZLg2CjjOwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5RHRM/btsQTrlaInc/W2jXAqQHrRaBZLg2CjjOwK/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;75.93&quot; style=&quot;width: 75.049%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5RHRM/btsQTrlaInc/W2jXAqQHrRaBZLg2CjjOwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5RHRM%2FbtsQTrlaInc%2FW2jXAqQHrRaBZLg2CjjOwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VvZKO/btsQTUm9mhv/IyQrlCy9KQktyJyeY7bQvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VvZKO/btsQTUm9mhv/IyQrlCy9KQktyJyeY7bQvk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-filename=&quot;blob&quot; style=&quot;width: 23.7882%;&quot; data-widthpercent=&quot;24.07&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VvZKO/btsQTUm9mhv/IyQrlCy9KQktyJyeY7bQvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVvZKO%2FbtsQTUm9mhv%2FIyQrlCy9KQktyJyeY7bQvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OTw32/btsQR03wvoV/j74LI2Ye6peHRuLGDYc5mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OTw32/btsQR03wvoV/j74LI2Ye6peHRuLGDYc5mK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;50&quot; style=&quot;width: 49.4186%; margin-right: 10px; margin-top: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OTw32/btsQR03wvoV/j74LI2Ye6peHRuLGDYc5mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOTw32%2FbtsQR03wvoV%2Fj74LI2Ye6peHRuLGDYc5mK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v6zHh/btsQQYrj6OT/cmRTSilYXXoaIfEnJIFzak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v6zHh/btsQQYrj6OT/cmRTSilYXXoaIfEnJIFzak/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.4186%; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v6zHh/btsQQYrj6OT/cmRTSilYXXoaIfEnJIFzak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv6zHh%2FbtsQQYrj6OT%2FcmRTSilYXXoaIfEnJIFzak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mEC5n/btsQRzkwpnH/q1akIe5YwIbtVQ4hxJN4Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mEC5n/btsQRzkwpnH/q1akIe5YwIbtVQ4hxJN4Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mEC5n/btsQRzkwpnH/q1akIe5YwIbtVQ4hxJN4Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmEC5n%2FbtsQRzkwpnH%2Fq1akIe5YwIbtVQ4hxJN4Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;오전 키노트 세션&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;오전에는 공통 키노트가 진행되었습니다, 기술적 핵심만 간단히 정리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;PlayMCP - AI 서비스 생태계의 출발점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qtWNB/btsQR9Miz7b/pkeUAJbV4BMNYbfn821km0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qtWNB/btsQR9Miz7b/pkeUAJbV4BMNYbfn821km0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qtWNB/btsQR9Miz7b/pkeUAJbV4BMNYbfn821km0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqtWNB%2FbtsQR9Miz7b%2FpkeUAJbV4BMNYbfn821km0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;모델과 서비스, 즉 에이전트가 외부 기능을 안전하게 호출하도록 연결하는 표준 프로토콜과 마켓&amp;middot;플레이그라운드 개념이 소개되었습니다. 세부적으로는 툴 등록과 권한 범위 선언, 컨텍스트 교환 형식, 호출 정책, 실행 기록 추적 같은 운영 포인트가 강조되었습니다. 개발자 관점에서 느낀 핵심은 두 가지였습니다. 첫째, 에이전트가 호출할 수 있는 기능을 능력 단위로 캡슐화해 상호 운용성을 높였다는 점. 둘째, 인증&amp;middot;과금&amp;middot;레이트리밋 같은 운영 레일이 프로토콜 레벨에서 고려되어 실서비스로 전환하기 쉽다는 점입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Agentic AI를 향한 카나나 모델의 진화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5rDlH/btsQSw1zmL9/qxqdNYMEIHvKANjT3NBcDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5rDlH/btsQSw1zmL9/qxqdNYMEIHvKANjT3NBcDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5rDlH/btsQSw1zmL9/qxqdNYMEIHvKANjT3NBcDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5rDlH%2FbtsQSw1zmL9%2FqxqdNYMEIHvKANjT3NBcDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;단순 응답형을 넘어 관찰(멀티모달 인지)-계획(체인&amp;middot;그래프 기반 플래닝)-행동(툴 실행) 루프를 붙이는 방향이 제시되었습니다. 프롬프트 기반 플래너와 경량 정책 모듈을 조합해 시나리오별 플로우를 안정적으로 재현하는 전략이 인상적이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;안전한 AI를 위한 카카오의 노력&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9Iqi2/btsQSqtOXRW/aCxGYWk9PHYRInJqNxcBb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9Iqi2/btsQSqtOXRW/aCxGYWk9PHYRInJqNxcBb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9Iqi2/btsQSqtOXRW/aCxGYWk9PHYRInJqNxcBb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9Iqi2%2FbtsQSqtOXRW%2FaCxGYWk9PHYRInJqNxcBb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;안전&amp;middot;품질 조직이 독립적으로 가드레일을 설계하고, 금칙행동 정의, PII 필터링, 심리&amp;middot;정치&amp;middot;의학 등 고위험 도메인에서의 방어 정책, 레드팀 라운드(모의 공격)와 휴리스틱&amp;middot;규칙&amp;middot;모델 앙상블을 결합한 검증 파이프라인을 운영한다는 점이 공유되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Kakao Re-engineering: AI-Native 전환&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfsVmz/btsQR80Ze1j/5OBelsNX4CtwklryokW1KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfsVmz/btsQR80Ze1j/5OBelsNX4CtwklryokW1KK/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfsVmz/btsQR80Ze1j/5OBelsNX4CtwklryokW1KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfsVmz%2FbtsQR80Ze1j%2F5OBelsNX4CtwklryokW1KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxSSB8/btsQSrfaonm/sKYgEXYXKwAedXeHkQDIOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxSSB8/btsQSrfaonm/sKYgEXYXKwAedXeHkQDIOK/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxSSB8/btsQSrfaonm/sKYgEXYXKwAedXeHkQDIOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxSSB8%2FbtsQSrfaonm%2FsKYgEXYXKwAedXeHkQDIOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OAVn5/btsQQVH8G1A/7T5q5IahT8CMewEjwuudf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OAVn5/btsQQVH8G1A/7T5q5IahT8CMewEjwuudf0/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OAVn5/btsQQVH8G1A/7T5q5IahT8CMewEjwuudf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOAVn5%2FbtsQQVH8G1A%2F7T5q5IahT8CMewEjwuudf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;데이터 플랫폼-모델 플랫폼-서빙 플랫폼을 수평 결합하고, 릴리즈&amp;middot;모니터링&amp;middot;세이프티 리뷰를 ML 파이프라인에 통합하는 전사 아키텍처 전환이 소개되었습니다. 특히 실험 관리와 재현성, 피드백 루프 자동화가 강조되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;[오전 세션 전체 : 다시보기]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/UING73fPHiU?si=rKAYT_IihP0tT52r&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;점심과 체험존&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EeBV7/btsQTq0RRIr/MGiLfHEg43JczxzoqiSKs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EeBV7/btsQTq0RRIr/MGiLfHEg43JczxzoqiSKs0/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EeBV7/btsQTq0RRIr/MGiLfHEg43JczxzoqiSKs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEeBV7%2FbtsQTq0RRIr%2FMGiLfHEg43JczxzoqiSKs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5kk9Z/btsQRJtGN1J/8S9C8zIwLMapHj3Hr7FfeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5kk9Z/btsQRJtGN1J/8S9C8zIwLMapHj3Hr7FfeK/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5kk9Z/btsQRJtGN1J/8S9C8zIwLMapHj3Hr7FfeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5kk9Z%2FbtsQRJtGN1J%2F8S9C8zIwLMapHj3Hr7FfeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGyi2V/btsQSs5XyNB/4qPlkhnIxzZNEWjVmKPi3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGyi2V/btsQSs5XyNB/4qPlkhnIxzZNEWjVmKPi3K/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 42.0491%; margin-right: 10px;&quot; data-widthpercent=&quot;43.05&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGyi2V/btsQSs5XyNB/4qPlkhnIxzZNEWjVmKPi3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGyi2V%2FbtsQSs5XyNB%2F4qPlkhnIxzZNEWjVmKPi3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbJOQo/btsQQUoRaeo/oLQ9CoqGYqsTSauAUt9EN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbJOQo/btsQQUoRaeo/oLQ9CoqGYqsTSauAUt9EN1/img.png&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;1327&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 13.5762%; margin-right: 10px;&quot; data-widthpercent=&quot;13.9&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbJOQo/btsQQUoRaeo/oLQ9CoqGYqsTSauAUt9EN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbJOQo%2FbtsQQUoRaeo%2FoLQ9CoqGYqsTSauAUt9EN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;1327&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2fVrQ/btsQRFyAHv4/K6hcqvBgwuBBLcX8ymqhMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2fVrQ/btsQRFyAHv4/K6hcqvBgwuBBLcX8ymqhMk/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 42.0491%;&quot; data-widthpercent=&quot;43.05&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2fVrQ/btsQRFyAHv4/K6hcqvBgwuBBLcX8ymqhMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2fVrQ%2FbtsQRFyAHv4%2FK6hcqvBgwuBBLcX8ymqhMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;점심 도시락은 치킨, 유부초밥, 과일로 구성이 되어있었고 스타벅스 음료와 생수가 넉넉했습니다. 체험존에서는 카나나 계열 모델과 다양한 데모를 직접 사용을 할 수 있었고 스티커를 모아 럭키드로우에 응모하는 이벤트가 진행되었습니다. 즐겁게 돌아다녔지만 아쉽게 경품은 뱃지와 체험권을 받아 조금은 실망은 했지만 체험은 재미있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;오후 기술 세션&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;LLM은 있지만 다시 학습하고 싶어 - Kanana-2 개발기 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/B7sc-OlnkCE?si=1pQNkan-53rcoBj7&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Kanana-2는 프리트레이닝 스케일과 데이터 구성을 재설계해 범용성과 실서비스 적합성을 동시에 노립니다. 코드와 수학 비중을 크게 늘렸고, 데이터 중복 제거&amp;middot;라이선스 정합성&amp;middot;오류 주입 방지 규칙을 고도화해 텍스트 품질을 개선했습니다. 모델 구조는 Mixture of Experts로 전환해 토큰당 활성화되는 이 전문가 수를 조절하며 연산 효율을 높였습니다. 라우터 손실과 부하균형 패널티로 전문가 쏠림을 방지하고, 토큰 라우팅 로그를 분석해 비정상 라우팅을 조기에 탐지하는 운영 팁도 공유되었습니다. 컨텍스트 확장은 MLA류 기법과 RoPE 스케일 전략을 병행했고, 사후 정렬 단계에서는 지시 따르기, 함의&amp;middot;추론, 함수호출, 안전 정책 따르기 등 다축 학습을 별도로 돌린 뒤 점진적으로 합치는 하이브리드 레시피가 소개되었습니다. 중요한 메시지는 성능 숫자만이 아니라 회귀 방지와 안정 추론, 호환성 같은 사용자 체감 지표를 동등하게 관리하는 개발 문화였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/EQTSy/dJMb9MbJp2q/QOK6AkJNCkPNkt16nVBkBK/01.LLM%EC%9D%80%20%EC%9E%88%EC%A7%80%EB%A7%8C%20%EB%8B%A4%EC%8B%9C%20%ED%95%99%EC%8A%B5%ED%95%98%EA%B3%A0%20%EC%8B%B6%EC%96%B4%20%26ndash%3B%20Kanana-2%20%EA%B0%9C%EB%B0%9C%EA%B8%B0%28%7Eing%29_.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;01.LLM은 있지만 다시 학습하고 싶어 &amp;amp;ndash; Kanana-2 개발기(~ing)_.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;4.55MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;데이터는 없지만 LLM은 학습하고 싶어 - Code/Math 데이터 개발기 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/cL_UjE38_8Q?si=Og9JTkusnmRTpCNC&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;대규모 고품질 데이터의 병목을 해결한 방법이 인상적이었습니다. 코드 쪽은 리포지토리 건강도 지표(스타, 최근 커밋, CI 상태), 라이선스, 중복률, 실행 성공률로 필터링하고, 파서 기반 토큰화&amp;middot;AST 정규화&amp;middot;주석 노이즈 처리로 학습 친화도를 올렸습니다. 수학 쪽은 OCR 파이프라인에 수식 렌더 복구, 표 구조 복원, 레이아웃 프롬프트 힌트 삽입을 추가해 망가진 수식을 되살렸습니다. 약지도(weak supervision)는 규칙&amp;middot;LLM 보조 라벨러&amp;middot;휴리스틱을 섞어 품질을 끌어올렸고, 샘플 난이도 스코어로 커리큘럼을 구성해 초반에는 기초, 후반에는 복합 추론&amp;middot;증명류를 강화했습니다. 이런 데이터 공학 덕분에 코드 생성&amp;middot;테스트 통과율, 수학 태스크의 연쇄추론 안정성이 체감적으로 향상되었다는 점이 설득력 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cIBQ1j/dJMb9Om5hTv/say6lrppuDigcC9Ku34mL1/02.%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%8A%94%20%EC%97%86%EC%A7%80%EB%A7%8C%20LLM%EC%9D%80%20%ED%95%99%EC%8A%B5%ED%95%98%EA%B3%A0%20%EC%8B%B6%EC%96%B4%20-%20Code%2C%20Math%20%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EA%B0%9C%EB%B0%9C%EA%B8%B0.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02.데이터는 없지만 LLM은 학습하고 싶어 - Code, Math 데이터 개발기.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;3.07MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;LLM은 있지만 컨텍스트가 짧아 - Long Context 실전 적용기 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/mFHjPLa_d-4?si=eSCzdDaxHLiDuwoU&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;여기서는 윈도 크기 숫자보다 운영 노하우가 핵심이었습니다. 포지셔널 임베딩은 RoPE 스케일링, YaRN/LongRoPE 계열 변형을 태스크별로 A/B했고, 긴 맥락에서 앞&amp;middot;뒤 정보 편향을 줄이기 위해 섹션 앵커 토큰과 헤더 힌트를 넣어 검색 부담을 낮췄습니다. 모델을 건드리지 않는 방법으로는 검색 강화(RAG)와 계층 요약을 조합해 비용을 통제했고, 생성 단계에서는 plan-then-answer 전략과 끊김 없는 스트리밍을 적용했습니다. 평가도 단순 F1이 아니라 위치 민감도(정답 위치 오프셋), 기억 지속성, 긴 대화 drift 여부, 실사용 로그 재현률까지 포함해 다면적으로 봤다는 점이 좋았습니다. 결론은 롱컨은 모델&amp;middot;프롬프트&amp;middot;인덱싱&amp;middot;평가를 하나의 세트로 운영해야 실무에 녹아든다는 것이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bWrBUM/dJMb9MbJp2s/kZAtSiPHd9uKNN5RB3tIH1/03.LLM%EC%9D%80%20%EC%9E%88%EC%A7%80%EB%A7%8C%20%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EA%B0%80%20%EC%A7%A7%EC%95%84%20-%20Long%20Context%20%EC%8B%A4%EC%A0%84%20%EC%A0%81%EC%9A%A9%EA%B8%B0.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;03.LLM은 있지만 컨텍스트가 짧아 - Long Context 실전 적용기.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;5.46MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;눈으로 보고, 귀로 듣고, 입으로 말하는 AI - 통합 멀티모달 언어모델 Kanana-o &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/S4CMtHfscis?si=1zoop8yz1V-3j27d&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Kanana-o는 비전 인코더와 오디오 인코더를 언어모델에 적절한 어댑터를 통해 연결한 후, 멀티모달 지시튜닝과 선호정렬을 거쳐 완성된 통합 모델입니다. 이미지 쪽은 문서&amp;middot;UI&amp;middot;차트 같은 구조화 시각물에 강점이 보였고, 오디오 쪽은 스트리밍 ASR과 감정 포함 TTS, 턴테이킹 제어(VAD/바이브 모니터링)로 대화 자연스러움을 끌어올렸습니다. 데모에서 감정 음성 합성, 팟캐스트 스타일 대화 생성, 실시간 통역이 매끄럽게 돌아갔고, 한국어 멀티모달 태스크에서 강한 모습을 보였습니다. 실무 관점의 포인트는 입력 동기화와 지연 관리였습니다. 프레임 드롭 시 보수적 응답으로 전환, 비동기 모달의 타임스탬프 정합, 오디오-텍스트 상호검증으로 오류 전파를 줄이는 운영 팁이 유용했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;화면을 이해하고 행동하는 AI - GUI Agent 개발기 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/k-8CFgBhhu4?si=w_ZYDF4FzOBtZgBv&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;GUI Agent는 스크린샷&amp;middot;태스크 목표&amp;middot;액션 히스토리를 입력으로 받아, VLM이 UI 요소를 인지하고, 액션 파서가 click/type/drag/submit 같은 원자 행위를 생성하며, 실행기가 실제 브라우저나 앱을 조작하는 구조였습니다. 한국어 웹 데이터 부족을 자동 생성과 수작업 로그 수집으로 메웠고, 좌표 체계는 해상도 의존을 줄이기 위해 상대 좌표와 텍스트 앵커 바인딩을 병행했습니다. Heatmap 기반 손실로 정답 주변 허용 오차를 주어 실제 클릭 성공률을 끌어올린 점, 실패 로그를 원인별로 분류해 데이터 재주입 루프를 돌린 점이 눈에 띄었습니다. 벤치마크 시나리오는 예약&amp;middot;결제&amp;middot;민원&amp;middot;검색 중심으로 구성되어 현실성이 있었고, 프롬프트와 정책의 결합으로 계획 오류를 줄이는 방식이 효과적이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;카카오톡 AI 에이전트를 위한 온디바이스 모델 최적화 및 적용 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/8ggESRKrfZ4?si=IkL41oe8U-k8RayJ&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;온디바이스는 개인정보 보호, 지연&amp;middot;비용 절감을 위해 필연적인 선택이었습니다. 모델은 1-3B급 소형 모델을 기본으로 하고, 4/8비트 양자화로 메모리 발자국을 줄였습니다. iOS에서는 MLX와 CoreML을 혼용하고, GPU와 ANE를 태스크 특성에 따라 스위칭했습니다. 초기 컴파일 지연을 줄이기 위한 캐시 전략, KV 캐시 조각화 방지, 토크나이저 병렬화와 스트리밍 출력이 실사용 체감에 크게 기여했습니다. 전력&amp;middot;발열 대응으로는 토큰 초당 목표치에 맞춘 다이내믹 디코딩(탑K/탑P/온도)을 적용했고, 휴면 복귀 시 빠른 컨텍스트 재주입을 위한 메모리 맵핑을 사용했습니다. 중요한 교훈은 큰 모델의 과도한 압축보다 설계 단계에서 작은 모델을 제대로 선택&amp;middot;튜닝하는 쪽이 최적의 사용자 경험을 준다는 점이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bqYmYz/dJMb9Om5hUX/m78LWt6O0NbtpwKTxdw3J1/06.%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1%20AI%20%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8%EB%A5%BC%20%EC%9C%84%ED%95%9C%20%EC%98%A8%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4%20%EB%AA%A8%EB%8D%B8%20%EC%B5%9C%EC%A0%81%ED%99%94%20%EB%B0%8F%20%EC%A0%81%EC%9A%A9.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;06.카카오톡 AI 에이전트를 위한 온디바이스 모델 최적화 및 적용.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.23MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;행사종료 및 귀경&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;모든 일정이 끝난 뒤 오전 하차 지점에서 강남역행 셔틀을 탔습니다. 퇴근 시간 정체로 오전보다 두배 이상 걸렸고 비도 내려 근처 국수집에서 간단히 저녁을 해결했습니다. 이 후 2호선과 수인분당선으로 환승해 수서역으로 이동했고 SRT를 탑승하여 울산을 내려와 하루를 마무리했습니다. 장거리 일정이라 피곤했지만 머릿 속은 새로운 아이디어로 가득했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0W8xa/btsQQ1VWIQg/bA7kzJjpEtk11bKQFxcKRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0W8xa/btsQQ1VWIQg/bA7kzJjpEtk11bKQFxcKRk/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0W8xa/btsQQ1VWIQg/bA7kzJjpEtk11bKQFxcKRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0W8xa%2FbtsQQ1VWIQg%2FbA7kzJjpEtk11bKQFxcKRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9nHyJ/btsQUjtpqjX/Ctj240bZzRsAkzLWZgeeZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9nHyJ/btsQUjtpqjX/Ctj240bZzRsAkzLWZgeeZ1/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9nHyJ/btsQUjtpqjX/Ctj240bZzRsAkzLWZgeeZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9nHyJ%2FbtsQUjtpqjX%2FCtj240bZzRsAkzLWZgeeZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/erktmK/btsQSOAT6Ku/xUPficBGx7JBHGoi8BC4Q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/erktmK/btsQSOAT6Ku/xUPficBGx7JBHGoi8BC4Q0/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 42.1561%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;43.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/erktmK/btsQSOAT6Ku/xUPficBGx7JBHGoi8BC4Q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FerktmK%2FbtsQSOAT6Ku%2FxUPficBGx7JBHGoi8BC4Q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SMXrE/btsQTRqnCSF/3nItK9MbeEgnsSthP23PK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SMXrE/btsQTRqnCSF/3nItK9MbeEgnsSthP23PK1/img.png&quot; data-origin-width=&quot;1689&quot; data-origin-height=&quot;3000&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 13.3622%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;13.68&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SMXrE/btsQTRqnCSF/3nItK9MbeEgnsSthP23PK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSMXrE%2FbtsQTRqnCSF%2F3nItK9MbeEgnsSthP23PK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1689&quot; height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/doKaS7/btsQQVBoeed/Bmf76s3PCZdIMZNGzYPtVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doKaS7/btsQQVBoeed/Bmf76s3PCZdIMZNGzYPtVk/img.png&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1689&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 42.1561%; margin-top: 10px;&quot; data-widthpercent=&quot;43.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doKaS7/btsQQVBoeed/Bmf76s3PCZdIMZNGzYPtVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoKaS7%2FbtsQQVBoeed%2FBmf76s3PCZdIMZNGzYPtVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1689&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;if(kakao)25는 기술 쇼케이스를 넘어 실서비스에 AI를 녹여내는 운영 지혜를 배울 수 있는 자리였습니다. 데이터 엔지니어링, 모델 구조, 정렬, 롱컨 운영, 멀티모달 통합, GUI 에이전트, 온디바이스 최적화까지 전 과정을 한번에 조망할 수 있었습니다. 무엇보다도 각 팀이 성능 수치만이 아닌 회귀 방지, 안정성, 지연 비용, 안전같은 현실 지표를 동등하게 관리한다는 점이 크게 와 닿았습니다. 개발자로써 현업에 바로 가져다 쓸 수 있는 힌트를 많이 얻었습니다. 내년에도 기회가 된다면 다시 참여하고 싶습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;s&gt;(카카오톡 업데이트로 많은 이야기가 있어서 업데이트를 일부러 해봤습니다. 아직 적응이 안된 것때문에 불편한 것인지.. UI가 메신저가 아닌 인스타그램화 되어있는 것이 불편하고 왜 숏폼을 메신저에서 봐야하는지 이해도 안되는데... 여러분은 사용하실만한가요?)&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;script&gt;

(function(){
  document.querySelectorAll('iframe').forEach(function(f){
    var src = (f.getAttribute('src')||'').toLowerCase();
    var isYT = src.includes('youtube.com') || src.includes('youtu.be');
    var isMap = src.includes('maps.google') || src.includes('map.kakao') || src.includes('vworld');
    if(!(isYT||isMap)) return;
    if(f.closest('.media-wrap')) return;
    var wrap = document.createElement('div');
    wrap.className='media-wrap';
    f.parentNode.insertBefore(wrap, f);
    wrap.appendChild(f);
    f.setAttribute('loading','lazy');
    f.setAttribute('referrerpolicy','strict-origin-when-cross-origin');
    f.setAttribute('title', f.getAttribute('title') || (isYT ? 'YouTube video' : 'Map'));
    if(isYT &amp;&amp; !src.includes('mute=1')){
      var url = new URL(f.src);
      url.searchParams.set('mute','1');
      f.src = url.toString();
    }
  });

  document.querySelectorAll('.devconf-article a[href^=&quot;http&quot;]').forEach(function(a){
    a.rel = 'noopener noreferrer';
    if(!a.target) a.target = '_blank';
  });

  var heads = document.querySelectorAll(&quot;.tt_article_useless_p_margin h2, .tt_article_useless_p_margin h3&quot;);
  heads.forEach(function(h){
    if(!h.id){
      h.id = &quot;h-&quot; + h.textContent.trim().replace(/\s+/g,&quot;-&quot;).replace(/[^\w\-가-힣]/g,&quot;&quot;).toLowerCase();
    }
    if(!h.querySelector('.dev-anchor')){
      var a = document.createElement('a');
      a.href = &quot;#&quot;+h.id; a.className=&quot;dev-anchor&quot;; a.title=&quot;이 제목 링크&quot;;
      a.textContent = &quot;#&quot;;
      h.appendChild(a);
    }
  });

  document.querySelectorAll('.tt_article_useless_p_margin').forEach(function(scope){
    var html = scope.innerHTML;
    scope.innerHTML = html.replace(/\[##_File\|([^\|]+)\|([^\|]+)\|_##\]/g, function(_, url, meta){
      // meta 예: filename=&quot;xxx.pdf&quot; size=&quot;4.55MB&quot; data-ke-align=&quot;alignCenter&quot;
      var filename = (meta.match(/filename=&quot;([^&quot;]+)&quot;/)||[])[1] || 'attachment';
      var size = (meta.match(/size=&quot;([^&quot;]+)&quot;/)||[])[1] || '';
      var align = (meta.match(/data-ke-align=&quot;([^&quot;]+)&quot;/)||[])[1] || '';
      var alignCls = align==='alignCenter' ? ' style=&quot;justify-content:center&quot;' : '';
      return '&lt;div class=&quot;dev-file&quot;'+alignCls+'&gt;' +
             '&lt;span class=&quot;dev-file-ic&quot;&gt;PDF&lt;/span&gt;' +
             '&lt;div&gt;&lt;a href=&quot;'+url+'&quot; download&gt;'+filename+'&lt;/a&gt;&lt;br&gt;&lt;small&gt;'+ (size ? size : '') +'&lt;/small&gt;&lt;/div&gt;' +
             '&lt;/div&gt;';
    });
  });
})();
&lt;/script&gt;
&lt;script&gt;
(function(){
  var toc = document.querySelector('.dev-toc');
  if(!toc) return;

  var last = window.scrollY;
  var checkSticky = function(){
    var rect = toc.getBoundingClientRect();
    var shouldFix = rect.top &lt; 0 &amp;&amp; window.innerWidth &gt; 1024;
    toc.classList.toggle('is-fixed', shouldFix);
  };
  window.addEventListener('scroll', checkSticky, {passive:true});
  window.addEventListener('resize', checkSticky);
  checkSticky();
})();
&lt;/script&gt;
&lt;script&gt;
(function(){
  var scope = document.querySelector('.tt_article_useless_p_margin');
  if(!scope) return;

  scope.querySelectorAll('h1,h2,h3,h4').forEach(function(h){
    var txt = (h.textContent || &quot;&quot;).replace(/\u00a0/g,' ').trim(); // nbsp 제거
    if(!txt){ h.remove(); }
  });

  scope.querySelectorAll('h2,h3').forEach(function(h){
    if(!h.id){
      h.id = &quot;h-&quot; + h.textContent.trim().replace(/\s+/g,&quot;-&quot;).replace(/[^\w\-가-힣]/g,&quot;&quot;).toLowerCase();
    }
    if(!h.querySelector('.dev-anchor')){
      var a = document.createElement('a');
      a.href = &quot;#&quot;+h.id; a.className=&quot;dev-anchor&quot;; a.title=&quot;이 제목 링크&quot;;
      a.textContent = &quot;#&quot;;
      h.appendChild(a);
    }
  });

  if (window.jQuery &amp;&amp; jQuery.fn.toc){
    jQuery(&quot;#toc&quot;).empty().toc({
      content: &quot;.tt_article_useless_p_margin&quot;,
      headings: &quot;h1,h2,h3,h4&quot;,
      top: -90,
      isBlink : true,
      blinkColor : '#21B9DE'
    });
  }
})();
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>IT</category>
      <category>aiagent</category>
      <category>AI컨퍼런스</category>
      <category>IF카카오25</category>
      <category>LLM</category>
      <category>개발자</category>
      <category>온디바이스AI</category>
      <category>이프카카오25</category>
      <category>참가후</category>
      <category>카카오</category>
      <category>카카오ai</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/552</guid>
      <comments>https://odinbox.tistory.com/552#entry552comment</comments>
      <pubDate>Sun, 28 Sep 2025 07:05:50 +0900</pubDate>
    </item>
    <item>
      <title>SQL JOIN문법, 데이터베이스(DB) 테이블 결합의 모든 것</title>
      <link>https://odinbox.tistory.com/551</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;SQL JOIN 종류(INNER &amp;middot; LEFT &amp;middot; RIGHT &amp;middot; FULL OUTER)의 개념 차이를 예제로 정리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;font-weight: normal; position: relative; line-height: 40px; background: #007CBA; border: 1px solid #fff; padding: 10px; color: white; border-radius: 0 10px 0 10px; box-shadow: inset 0 0 5px rgba(53,86,129, 0.5); font-family: 'Muli', sans-serif; border-style: solid; border-width: 0px 0px 1px 15px; border-color: #232323; background-color: #007cba;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;헷갈리는 SQL JOIN, 한 번에 정리해 봅시다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;SQL JOIN 종류 정리 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIELNc/btsQI4XQ0IJ/XFD7IMo1BhjSDma8K7KeZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIELNc/btsQI4XQ0IJ/XFD7IMo1BhjSDma8K7KeZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIELNc/btsQI4XQ0IJ/XFD7IMo1BhjSDma8K7KeZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIELNc%2FbtsQI4XQ0IJ%2FXFD7IMo1BhjSDma8K7KeZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;SQL JOIN 종류 정리 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;관계형 데이터베이스에서는 정보가 여러 테이블로 정규화되어 나뉘어 저장됩니다. 예를 들어 직원 정보와 부서 정보를 별도 테이블에 분리해 두는 경우, 필요한 데이터를 한 곳에서 조회하려면 테이블을 조인해야 합니다. JOIN은 데이터베이스 내 여러 테이블의 레코드를 조합하여 하나의 결과 집합으로 표현해 주는 SQL 구문으로, 두 테이블 간 공통 필드의 값을 기준으로 행들을 연결합니다. 이를 통해 마치 하나의 테이블에 있던 것처럼 데이터를 결합하여 활용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;SQL 표준에는 여러 JOIN이 있지만, 실무에서 주로 사용하는 것은 &lt;b&gt;INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN&lt;/b&gt; 네 가지입니다. 각 JOIN은 포함하는 데이터 범위에 차이가 있으므로, 용도에 맞게 올바른 JOIN을 선택하는 것이 중요합니다. 이 글에서는 직원&amp;middot;부서 테이블 예제로 네 가지 JOIN의 차이를 결과까지 비교하며 정리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-style: solid; font-weight: bold; border-width: 1px 1px 1px 5px; border-color: #707070; background-color: #fff; padding: 10px;&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	$(&quot;#toc&quot;).toc( {content: &quot;.tt_article_useless_p_margin&quot;, headings: &quot;h1,h2,h3,h4&quot; , top: -90, isBlink : true, blinkColor : '#21B9DE' } ) });
&lt;/script&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SQL JOIN 예제 준비&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;예시 테이블 생성&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1758389169773&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 직원 테이블 생성
CREATE TABLE Employee (
    EmpID INT PRIMARY KEY,
    EmpName VARCHAR(50),
    BirthYear INT,
    DeptID INT
);

-- 부서 테이블 생성
CREATE TABLE Department (
    DeptID INT PRIMARY KEY,
    DeptName VARCHAR(50)
);

-- 직원 데이터 입력
INSERT INTO Employee (EmpID, EmpName, BirthYear, DeptID) VALUES
(1, '최영환', 1994, 30),
(2, '홍길동', 1950, 20),
(3, '신형만', 1983, 15);

-- 부서 데이터 입력
INSERT INTO Department (DeptID, DeptName) VALUES
(30, '솔루션개발'),
(20, '경영지원'),
(15, 'DX사업부'),
(40, '스마트팩토리'); -- 직원 없는 부서&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;두 테이블을 잇는 공통 키는 &lt;code&gt;DeptID&lt;/code&gt;입니다. 직원 3명은 모두 부서가 있고, 부서 4개 중 '스마트팩토리(40)'에는 소속 직원이 없습니다. 이 비대칭 덕분에 JOIN 종류에 따라 결과가 어떻게 달라지는지 명확히 비교할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;INNER JOIN (내부 조인) &amp;mdash; 교집합 조회&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPUq6T/btsQGrmM5V7/EXOHWVGoak6fRKNMk0dEbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPUq6T/btsQGrmM5V7/EXOHWVGoak6fRKNMk0dEbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPUq6T/btsQGrmM5V7/EXOHWVGoak6fRKNMk0dEbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPUq6T%2FbtsQGrmM5V7%2FEXOHWVGoak6fRKNMk0dEbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1212&quot; height=&quot;733&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;INNER JOIN은 두 테이블에서 공통으로 일치하는 레코드만 결합하여 반환합니다. 조건에 양쪽 모두 존재하는 데이터만 결과에 포함되므로, 어느 한쪽에만 존재하는 데이터는 빠집니다. 일반적으로 &lt;code&gt;JOIN&lt;/code&gt; 키워드만 사용하면 기본적으로 INNER JOIN으로 동작하며, 가장 흔히 쓰이는 조인 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;직원(Employee) 테이블과 부서(Department) 테이블을 &lt;code&gt;Employee.DeptID&lt;/code&gt;와 &lt;code&gt;Department.DeptID&lt;/code&gt;를 기준으로 INNER JOIN 하면, 부서가 할당된 직원들만 조회됩니다. 부서가 없는 직원이나, 직원이 한 명도 없는 부서는 결과에서 제외됩니다. 즉 양쪽 모두에 존재하는 교집합 데이터만 얻습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예시 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1758389227627&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT e.EmpName, e.BirthYear, d.DeptName
FROM Employee e
INNER JOIN Department d
    ON e.DeptID = d.DeptID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;EmpName&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;BirthYear&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;DeptName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;최영환&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1994&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;솔루션개발&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;홍길동&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1950&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;경영지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;신형만&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1983&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;DX사업부&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;직원 3명이 모두 실제 부서와 연결되므로 전부 표시되고, 직원이 없는 '스마트팩토리'는 제외됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;LEFT JOIN (좌측 조인) &amp;mdash; 왼쪽 테이블 모두 포함&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/luYWf/btsQIKyxCzF/VKt5Jy2zKNRdZ9fvrjFcqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/luYWf/btsQIKyxCzF/VKt5Jy2zKNRdZ9fvrjFcqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/luYWf/btsQIKyxCzF/VKt5Jy2zKNRdZ9fvrjFcqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FluYWf%2FbtsQIKyxCzF%2FVKt5Jy2zKNRdZ9fvrjFcqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1212&quot; height=&quot;733&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;LEFT JOIN은 왼쪽 테이블의 모든 행을 결과에 유지하면서, 오른쪽 테이블에서 일치하는 행을 결합합니다. 오른쪽에 대응되는 값이 없으면 해당 칼럼은 NULL로 채워진 채 결과에 포함됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;직원(Employee)을 왼쪽에 두고 부서(Department)와 LEFT JOIN 하면 모든 직원이 결과에 나타납니다. 부서가 있는 직원은 부서명이 표시되고, 부서가 없는 직원도 결과에 나오되 부서명이 NULL로 표시됩니다. 반대로 직원이 없는 부서는 결과에 나타나지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;LEFT JOIN은 주요 데이터 세트(왼쪽)의 손실 없이 부가 정보를 합칠 때 많이 사용됩니다. 또한 &lt;code&gt;WHERE d.DeptID IS NULL&lt;/code&gt; 조건을 더하면 &quot;왼쪽에는 있지만 오른쪽에는 없는 데이터&quot;를 쉽게 찾을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예시 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1758389289186&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT e.EmpName, e.BirthYear, d.DeptName
FROM Employee e
LEFT JOIN Department d
    ON e.DeptID = d.DeptID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;EmpName&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;BirthYear&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;DeptName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;최영환&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1994&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;솔루션개발&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;홍길동&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1950&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;경영지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;신형만&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1983&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;DX사업부&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;현재 데이터에서는 모든 직원이 부서와 매칭되므로 INNER JOIN과 결과가 같습니다. 만약 부서 없는 직원이 있었다면 그 직원도 표시되며 DeptName이 NULL로 나옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;RIGHT JOIN (우측 조인) &amp;mdash; 오른쪽 테이블 모두 포함&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xgOVW/btsQHTP9MaZ/rInr9AURJlQNhbyzUj6WU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xgOVW/btsQHTP9MaZ/rInr9AURJlQNhbyzUj6WU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xgOVW/btsQHTP9MaZ/rInr9AURJlQNhbyzUj6WU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxgOVW%2FbtsQHTP9MaZ%2FrInr9AURJlQNhbyzUj6WU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1213&quot; height=&quot;733&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;RIGHT JOIN은 LEFT JOIN과 반대로 오른쪽 테이블의 모든 행을 유지하면서, 왼쪽 테이블에서 일치하는 행을 결합합니다. 왼쪽에 대응되는 값이 없으면 NULL로 표시됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;부서(Department)를 오른쪽에 두고 직원(Employee)과 RIGHT JOIN 하면 모든 부서가 결과에 나타납니다. 직원이 없는 부서는 부서명이 표시되지만 직원 칼럼은 NULL로 나타납니다. 반대로 부서가 없는 직원은 결과에서 제외됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;RIGHT JOIN은 LEFT JOIN과 기능이 대칭적이지만, 대부분의 경우 테이블 순서를 바꿔 LEFT JOIN으로 같은 결과를 얻을 수 있어 실무에서는 자주 쓰이지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예시 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1758389358448&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT e.EmpName, e.BirthYear, d.DeptName
FROM Employee e
RIGHT JOIN Department d
    ON e.DeptID = d.DeptID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;EmpName&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;BirthYear&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;DeptName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;최영환&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1994&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;솔루션개발&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;홍길동&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1950&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;경영지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;신형만&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1983&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;DX사업부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;스마트팩토리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;모든 부서가 표시되고, 직원이 없는 '스마트팩토리'는 EmpName&amp;middot;BirthYear가 NULL로 나옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;FULL OUTER JOIN (풀 아우터 조인) &amp;mdash; 전체 합집합 조회&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBEnDA/btsQIWlf5BM/UbLULBFT2c6fkeKdNxuFe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBEnDA/btsQIWlf5BM/UbLULBFT2c6fkeKdNxuFe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBEnDA/btsQIWlf5BM/UbLULBFT2c6fkeKdNxuFe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBEnDA%2FbtsQIWlf5BM%2FUbLULBFT2c6fkeKdNxuFe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1214&quot; height=&quot;733&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;FULL OUTER JOIN은 왼쪽과 오른쪽 테이블의 모든 행을 포함하여 결합하는 방식입니다. 교집합뿐 아니라 한쪽에만 존재하는 데이터까지 모두 합쳐 보여줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;직원(Employee)과 부서(Department)를 FULL OUTER JOIN 하면 모든 직원과 모든 부서가 결과에 포함됩니다. 부서가 없는 직원은 부서 칼럼이 NULL로, 직원이 없는 부서는 직원 칼럼이 NULL로 표시됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;단, 일부 DBMS(MySQL 8.0 등)는 FULL OUTER JOIN을 지원하지 않습니다. 이 경우 LEFT JOIN 결과와 RIGHT JOIN 결과를 &lt;code&gt;UNION&lt;/code&gt;으로 합쳐 동일한 효과를 낼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예시 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1758389440780&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT e.EmpName, e.BirthYear, d.DeptName
FROM Employee e
FULL OUTER JOIN Department d
    ON e.DeptID = d.DeptID;

-- MySQL 등 FULL OUTER JOIN 미지원 DBMS에서는 아래처럼 우회
SELECT e.EmpName, e.BirthYear, d.DeptName
FROM Employee e LEFT JOIN Department d ON e.DeptID = d.DeptID
UNION
SELECT e.EmpName, e.BirthYear, d.DeptName
FROM Employee e RIGHT JOIN Department d ON e.DeptID = d.DeptID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;EmpName&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;BirthYear&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;DeptName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;최영환&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1994&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;솔루션개발&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;홍길동&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1950&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;경영지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;신형만&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;1983&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;DX사업부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;스마트팩토리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;직원 3명과 부서 4개가 모두 표시됩니다. '스마트팩토리'는 직원이 없어 직원 칼럼이 NULL이고, 만약 부서 없는 직원이 추가되면 그 직원은 DeptName이 NULL로 나옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;JOIN 종류 한눈에 비교&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;JOIN&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;의미&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;포함 범위&lt;/th&gt;
&lt;th style=&quot;border: 1px solid #ccc; padding: 6px; background: #f4f8ff;&quot;&gt;예제 결과 행 수&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;INNER JOIN&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;교집합&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;양쪽 모두 존재하는 행만&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;3행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;LEFT JOIN&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;왼쪽 기준&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;왼쪽 전부 + 일치하는 오른쪽&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;3행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;RIGHT JOIN&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;오른쪽 기준&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;오른쪽 전부 + 일치하는 왼쪽&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;4행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;FULL OUTER JOIN&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;합집합&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;양쪽 모든 행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid #ccc; padding: 6px;&quot;&gt;4행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;네 가지 JOIN을 요약하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;INNER JOIN&lt;/b&gt; &amp;mdash; 교집합. 양쪽에 모두 존재하는 데이터만 조회.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;LEFT JOIN&lt;/b&gt; &amp;mdash; 왼쪽 기준. 왼쪽 데이터는 모두 유지, 오른쪽에 없는 값은 NULL.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;RIGHT JOIN&lt;/b&gt; &amp;mdash; 오른쪽 기준. 오른쪽 데이터는 모두 유지, 왼쪽에 없는 값은 NULL.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;FULL OUTER JOIN&lt;/b&gt; &amp;mdash; 합집합. 양쪽 모든 데이터를 다 보여줌.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추가 팁&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;조인 칼럼에 인덱스를 걸면 성능이 크게 향상됩니다. 또한 너무 많은 테이블을 한 번에 조인하면 쿼리가 복잡해지고 성능 저하가 발생할 수 있으므로, 필요하면 뷰나 서브쿼리로 나누는 것이 좋습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;JOIN의 기본 원리를 이해하면 원하는 데이터를 빠뜨리지 않고 정확하게 조회할 수 있습니다. 상황에 맞는 JOIN을 선택하여 효율적인 데이터 결합을 해보세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>Full Outer Join</category>
      <category>INNER JOIN</category>
      <category>LEFT JOIN</category>
      <category>RIGHT JOIN</category>
      <category>SQL</category>
      <category>sql문법</category>
      <category>관계형데이터베이스</category>
      <category>데이터분석</category>
      <category>조인</category>
      <category>쿼리</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/551</guid>
      <comments>https://odinbox.tistory.com/551#entry551comment</comments>
      <pubDate>Sun, 21 Sep 2025 02:54:45 +0900</pubDate>
    </item>
    <item>
      <title>KT 소액결제 해킹 사건으로 본 펨토셀 유령 기지국의 위험</title>
      <link>https://odinbox.tistory.com/550</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;통신사 해킹, 개인정보는 언제 개인정보가 될 수 있는 건가요?&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;font-weight: normal; position: relative; line-height: 40px; background: #007CBA; border: 1px solid #fff; padding: 10px; color: white; border-radius: 0 10px 0 10px; box-shadow: inset 0 0 5px rgba(53,86,129, 0.5); font-family: 'Muli', sans-serif; border-style: solid; border-width: 0px  0px  1px 15px; border-color: #232323; background-color: #007cba;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;보이지 않는 위협, 유령기지국의 위험&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lVwzF/btsQzKLEIRn/w1BrMWBD6ZUevLlYZepRo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lVwzF/btsQzKLEIRn/w1BrMWBD6ZUevLlYZepRo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lVwzF/btsQzKLEIRn/w1BrMWBD6ZUevLlYZepRo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlVwzF%2FbtsQzKLEIRn%2Fw1BrMWBD6ZUevLlYZepRo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (1).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지난 9월 KT 통신망 이용자들을 대상으로 한 대규모 무단 소액결제 해킹 사건이 발생하여 사회적으로 큰 파장을 일으켰습니다. 특히 이번 사건에서는 일반인에게 생소한 펨토셀(FEMTOCELL) 일명 초소형 기지국이 해킹 도구로 악용되었다는 점에서 주목받고 있습니다. 펨토셀은 원래 실내나 음영 지역의 통신 품질을 높이기 위해 사용하는 손바닥 크기의 소형 기지국 장치인데요 이번 사건에서는 이러한 펨토셀이 유령기지국(불법 가짜 기지국)의 형태로 이용되어 다수 피해자의 휴대폰이 속아 접속하도록 만들고 이를 통해 소액결제 인증 절차를 가로챈 정황이 드러났습니다.&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-style: solid; font-weight: bold; border-width: 1px  1px  1px 5px; border-color: #707070; background-color: #fff; padding: 10px;&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	$(&quot;#toc&quot;).toc( {content: &quot;.tt_article_useless_p_margin&quot;, headings: &quot;h1,h2,h3,h4&quot; , top: -90, isBlink : true, blinkColor : '#21B9DE' } ) });
&lt;/script&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;KT 해킹(FEMTOCELL)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;펨토셀(Femtocell)이란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;펨토셀은 이동통신사의 초소형 기지국 장비를 의미합니다. 일반 기지국보다 훨씬 소형이며 반경 수십 미터 이내의 좁은 범위에 이동통신 신호를 제공합니다. 주로 가정이나 소규모 사무실처럼 신호가 약한 장소의 음영지역 해소 및 트래픽 분산 목적으로 설치됩니다. 예컨대 지하나 건물 내부에서 휴대전화 신호가 약할 때 통신사가 제공한 펨토셀을 인터넷망에 연결해 두면 그 주변에서 휴대폰이 강한 신호로 통화와 데이터를 사용할 수 있게 해주는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;펨토셀은 단순한 중계기(repeater)와 달리 자체적으로 이동통신 신호를 생성하여 인터넷을 통해 통신사의 코어망(core network)에 직접 연결되는 것이 특징입니다. 즉, 펨토셀에 접속한 휴대전화의 통화나 데이터는 펨토셀 -&amp;gt; 가정용 인터넷망 -&amp;gt; 통신사 코어망으로 전달되어 처리됩니다. 이렇게 하면 통신사는 대형 기지국을 늘리지 않고도 실내 커버리지를 개선하고 메인 망의 부하를 줄일 수 있는 장점이 있습니다. 원래 통신품질 향상을 위한 편리한 장치인 펨토셀이지만 보안이 취약할 경우 승인되지 않은 장비가 통신망에 접속하여 악용될 소지가 있다는 점이 이번 사건으로 드러났습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사건 개요, KT 유령 기지국 소액결제 해킹&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/9MOhwpz2AsQ?si=9CNqKsE9MT9SaoAr&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2025년 8월 말부터 9월 초 사이 KT 통신망을 사용하는 일부 휴대폰 가입자들이 자신도 모르는 사이에 무단으로 소액결제가 이루어지는 피해가 발생했습니다. 예를 들어 모바일 상품권 구매나 선불 교통카드 충전 등의 소액결제가 본인 승인 없이 이뤄져 경찰에 신고된 것입니다. 첫 피해신고는 8월 27일경 접수되었으며 주로 서울 금천구, 영등포구, 경기 광명시 일대 등 특정지역에서 피해 사례가 집중됐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;KT 내부 족사에 따르면 9월 11일까지 파악된 피해만 최소 278건에 약 1억 7천만 원의 금액이 본인 모르게 결제된 것으로 집계되었습니다. 이 사건은 오직 KT 망 이용자들에게서만 발생했으며 SKT나 LG U+ 등 다른 통신사 가입자 피해는 보고되지 않았습니다. KT는 9월 5일 새벽 자체 모니터링으로 이상 징후를 감지하고 해당 결제 트래픽을 차단했지만 초기에 이를 단순 스미싱 악성앱 감염으로 오인하여 사고 대응이 늦어졌습니다. 이후 9월 8일 네트워크 상에서 등록되지 않은 정체불명의 기지국 신호를 발견하고 나서야 비로소 해킹 정황을 인지 KISA(한국인터넷진흥원)에 사고를 공식 신고하게 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;조사 결과 피해자들의 휴대폰이 한때 접속했던 특정 기지국 ID가 KT망에 등록된 적 없는 불법 기지국으로 확인되었습니다. 쉽게 말해 해커들이 합법적인 KT기지국인 척 위장한 유령 기지국을 운용하여 피해자 휴대폰을 자기 장비로 끌어들였던 것입니다. 해당 기지국 ID는 KT 네트워크 상에 존재하지 않는 번호였기에 의심을 샀고 KT는 이를 즉시 차단했습니다. 이러한 불법 초소형 기지국을 이용한 해킹 사건은 국내 최초로 기록되었으며 수법의 특이성과 치밀한 때문에 수사 당국과 보안 업계의 이목이 집중되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;펨토셀 해킹 수법, 어떻게 결제를 가로챘나?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;그렇다면 해커들은 어떻게 펨토셀을 통해 남의 휴대폰 결제를 몰래 진행할 수 있었을까요? 현재까지 드러난 바를 종합했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/9wMrHOVmpJo?si=eHRhUXucvmsMKnsy&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;- IMSI 탈취 - 가입자 식별정보 가로채기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;펨토셀에 접속한 휴대전화는 통신망에 등록하기 위해 단말 고유식별번호를 기지국에 전송합니다. LTE망의 경우 단말 전원을 껐다 켜거나 할 때 IMSI(International Mobile Subscribar Identity, 국제이동가입자식별번호)를 보내면, 네트워크가 이를 확인하고 임시 id인 GUTI를 발급하여 통신을 진행합니다. IMSI는 유심(USIM)에 내장된 가입자 고유 번호로 이동통신사가 가입자를 인식하는 데&amp;nbsp; 사용되는 중요한 개인정보입니다. 이번 사건에서 해커의 불법 기지국에 일단 휴대폰이 접속되면 IMSI 등의 가입자 정보가 해커 장비로 유출되는 상황이 발생했습니다. 실제로 약 1만 9천 명의 KT 고객이 한 때 이 유령 기지국 신호를 잡았고 이 중 5,561명은 IMSI가 유출되었을 가능성이 있다고 확인되었습니다. IMSI가 유출될 경우 해커는 그 정보를 이용해 통신 트래픽을 중간에서 가로채거나 사용자를 가장할 수 있기 때문에 매우 위험합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;한편 5G의 경우 보안을 강화하여 IMSI 대신 암호화된 식별자를 사용하기 때문에 이러한 공격에 비교적 안전하지만 이번 사고는 LTE망을 노렸기에 IMSI 노출이 이루어진 것으로 분석됩니다. IMSI를 탈취한 해커는 곧이어 해당 가입자 명의로 소액결제를 시도한 것으로 보입니다.&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;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdNdv3/btsQzwNsXKf/MihL4rqV6HIyweEQf9b04k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdNdv3/btsQzwNsXKf/MihL4rqV6HIyweEQf9b04k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdNdv3/btsQzwNsXKf/MihL4rqV6HIyweEQf9b04k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdNdv3%2FbtsQzwNsXKf%2FMihL4rqV6HIyweEQf9b04k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;424&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 가짜 기지국을 통한 인증 가로채기&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;모바일 소액결제를 진행하려면 보통 본인확인 절차로 휴대폰 명의자의 이름, 생년월일, 주민등록번호 일부 등을 입력하고 ARS 전화 인증 또는 SMS 인증을 거쳐야 합니다. 일반적인 상황에서는 사용자의 휴대폰으로 통신사 인증번호가 문자로 오거나 ARS 전화가 와서 본인이 직접 이를 확인/승인해야 결제가 완료됩니다. 그런데 해커는 유령기지국에 연결된 피해자 폰의 통신을 통제함으로써 인증 요청 전화나 문자를 가로채고 대신 승인 절차를 진행한 것으로 추정됩니다. 즉, 통신사망 입장에선 해당 휴대폰이 정상적으로 ARS 인증을 완료한 것처럼 보이게 만들어 결제를 승인시켰다는 시나리오입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;아직 구체적으로 해커가 ARS 인증을 어떤 방식으로 우회 했는지 명확히 밝혀지지 않았으며 수사 중인 부분입니다. ARS 인증 시 요구되는 개인정보(예 : 주민번호 등)는 펨토셀만으로는 알아낼 수 없기 때문에 해커가 사전에 유출된 개인정보 DB를 입수하여 사용했거나 내부 협조자가 있었는지 등의 가능성이 제기되고 있습니다. KT측도 &quot;미등록 장비가 코어망에 어떻게 접속했는지 또 소액결제가 어떤 메커니즘으로 이뤄졌는지 추가 조사를 필요하다&quot;라고 밝혔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;- 통신장비 악용 - KT 기지국 장비 도용 의혹&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;한편 이번 사건의 유령 기지국 장비는 고가에 KT에서 실제 사용되던 펨토셀 장비가 유출되어 악용된 정황이 제기되었습니다. KT는 기자 브리핑에서 &quot;해당 불법 기지국이 기존에 KT망에 연결된 적이 있는 장비로 추정된다.&quot;라고 밝혔습니다. 현재 실물이 확보되지 않아 단정할 수 없지만 만약 과거에 쓰다 철거한 펨토셀 기기를 해커가 입수해 ID를 위조/도용했다면 통신망 인증을 쉽게 통과했을 가능성이 있습니다. 실제로 KT는 &quot;관리 시스템에 없는 장비는 개통되지 않도록 조치하고 있는데 이번 발견된 장비는 아마 철거 과정에서 ID가 삭제된 장비가 도용된 것 같다&quot;라고 설명했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;다시 말해 해커가 통신사 관리망 바깥에 있는 펨토셀을 불법 개통시킨 것이 아니라 원래 KT망에 등록되었던 장비를 어떤 방식으로 다시 불법 활용했을 가능성이 높다는 것입니다. 이는 통신장비 관리의 허점을 노린 것으로 볼 수 있어 향후 유사 수법에 대한 대비의 필요성을 시사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;드러난 피해와 보안상 문제점&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이번 해킹을 통해 드러난 피해 규모와 보안 문제점은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/x3nMzIL0oS8?si=U_rveP11WZ9CDmHl&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;* 무단 소액결제 피해&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;앞서 언급했듯이 확인된 무단 결제 건수만 수백 건에 달합니다. 피해자들은 자신이 결제한 적 없는 상품권 구매 내역등을 통신요금 청구서나 결제 알림을 통해 뒤늦게 인지한 경우가 많았습니다. 다행히 KT는 피해금액 전액을 고객에게 청구하지 않기로 결정하여 피해자 부담은 없도록 조치했습니다. 그러나 해커들은 이 과정에서 실제 금전적인 이득을 취했을 가능성이 높습니다. 예를 들어 구매된 상품권이나 충전금은 해커가 되팔았을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;* 개인정보(IMSI) 유출&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;5천여 명의 고객 IMSI가 노출되었을 가능성이 확인됨에 따라 이는 잠재적인 2차 피해 위협으로 이어집니다. IMSI 등 유심 정보가 유출되면 향후 동일 수법으로 통신 도청이나 추가 사기가 발생할 수 있으므로 해당 고객들은 유심 교체 및 보호서비스가 권고되고 있습니다. KT는 IMSI 노출 가능성이 있는 고객 전원에게 개별 안내를 보내어 희망 시 무상 유심 교체와 USIM 보안서비스를 제공하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;* 통신 인프라 보안 허점 노출&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;통신사들은 공식 승인된 기지국 장비만 자사 망에 접속되도록 관리해 왔지만 이번 사건으로 그 관리 체계의 허점이 드러났습니다. 폐기되었거나 권한이 말소된 장비가 다시 이용될 수 있었던 점, 그리고 일정기간 동안 통신사 내부에서 이를 탐지하지 못한 점은 보안적 개선이 필요한 부분입니다. 또한 기지국 인증과 통신 프로토콜 측면에서의 취약점도 지적됩니다. 예를 들어 휴대폰이 기지국을 선택할 때 신호 세기가 강하면 일단 접속하도록 설계된 구조상 해커는 합법 기지국 신호를 교란하거나 더 강한 신호로 유인하여 쉽게 단말을 가로챌 수 있었습니다. 더구나 4G LTE에서는 IMSI가 평문으로 노출되는 과정이 있었는데 이는 이전부터 IMSI 캐처(Stingray)등으로 악용 가능성이 제기되어 온 부분입니다. 실제로 2013년 Black Hat 해커 컨퍼런스에서도 연구자들이 해킹된 펨토셀을 사용해 인근 휴대폰의 음성통화, 문자, 인터넷 트래픽을 모두 도청 및 기록해 보이는 시연을 한 바 있습니다. 이처럼 가짜 기지국 공격은 해외에서는 이미 알려진 기법이며 우리나라에서도 현실화된 첫 사례가 발생한 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;대응 조치 및 재발 방지 대책&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사고 발생 후 정부와 KT를 비릇한 통신업계는 급히 대응 조치에 나섰습니다. 우선 과학기술정보통신부는 해당 사안을 중대한 통신망 침해사고로 보고 민, 관 합동조사단을 구성하였습니다. 또한 타 통신사들에게도 자사망에 유령 기지국이 존재하는지 긴급점검하도록 지시했고, SKT와 LG유플러스는 자체 점검 결과 이상이 없음을 보고했습니다. 고가기정통부는 만일 유사 피해가 발생할 경우 통신사가 피해금액을&amp;nbsp; 고객에게 청구하지 않도록 사전에 조치하라고 요청하였고 모든 통신사가 이를 수용한 상태입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;KT는 고객 대상 사과와 함께 다양한 보호 대책을 발표했습니다. 우선 이상 패턴의 소액결제 시도를 실시간 감지하여 자동 차단하고 결제 시 추가 본인확인(예 : ARS 비밀번호, 생체인증)을 거치도록 2차 인증을 강화했다고 밝혔습니다. 또한 피해 고객에 대한 전액 보상은 물론, 원인규명과 재발 방지를 위한 투자와 보안 인력 확충에 힘쓰겠다고 발표했습니다. 피해 공지가 부족했다는 지적에 따라 마이KT 앱과 웹사이트에 공지사항을 게시하고 고객이 직접 본인의 IMSI 유출 여부를 조회할 수 있는 기능도 제공했습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;초소형 기지국 관리 강화도 중요한 과제로 떠올랐습니다. 정부는 통신 3사에 일시적으로 신규 펨토셀 장비의 망접속을 전면 제한하도록 지시하며 추가적인 의심기기 접속을 차단했습니다. 향후 소형 기지국 보안 기준을 재정립하고 불법 기지국의 망 접속 시도를 실시간 탐지, 차단하는 기술적 대책도 마련할 계획입니다. 더불어 개인정보보호위원회는 이번 사태를 계기로 개인정보 안전관리 강화 방안을 발표하여 보안투자를 소홀히 한 기업에 대한 제재 강화와 위반 기업에 대한 과징금으로 피해자 구제 등에 나서겠다고 밝혔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;무엇보다 통신사들은 유사 사건 재발 방지를 위한 자사 관리 하에 운영되다 철거된 펨토셀 등 장비의 반출 및 폐기 절차를 엄격히 점검할 필요가 있습니다. 아울러 기지국 인증 시스템 상에서 사용 종료된 장치의 ID가 재사용되지 않도록 하고 비인가 기지국 탐지 시스템을 고도화해야 할 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;일반 이용자들을 위한 조언&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GtaEa/btsQymLBLYX/JU5ELRBTKLUfa6XRf556z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GtaEa/btsQymLBLYX/JU5ELRBTKLUfa6XRf556z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GtaEa/btsQymLBLYX/JU5ELRBTKLUfa6XRf556z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGtaEa%2FbtsQymLBLYX%2FJU5ELRBTKLUfa6XRf556z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;400&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-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이번 사건은 상당히 정교한 수법으로 진행되었기 때문에 일반 사용자가 개별적으로 예방하기는 어려운 측면이 있습니다. 그럼에도 불구하고 몇 가지 참고할만한 안전조치가 있습니다. 첫 번째는 휴대전화 소액결제를 평소 거의 사용하지 않는다면 통신사 고객센터나 앱을 통해 소액결제 한도를 0원으로 설정하거나 소액결제 차단/허용을 관리할 수 있도록 안내하고 있습니다. 실제로 KT는 이번 사고 이후 마이 KT앱에서 간편하게 소액결제 차단/허용을 관리할 수 있도록 안내하고 있습니다. 결제 수단을 원천봉인해 두면 설령 해커가 접근하더라도 결제를 시도할 수 없게 되므로 안심할 수 있습니다. 둘째,&amp;nbsp; 휴대폰에 갑자기 뜨는 이상한 기지국 명칭(평소와 다른 번호나 이름)이 확인되거나 평소 쓰던 4G/5G 데이터가 불통되고 2G로 표시되는 등 평소와 다른 통신 상태를 발견하면 주의가 필요합니다. 일본 사례에서는 해커의 차량이 나타나면 주변 휴대폰이 갑자기 2G로 전환되고 통신 장애가 발생했다고 합니다. 이러한 징후는 유령 기지국 개입 가능성을 의심해 볼 수 있으므로 반복된다면 통신사에 문의하거나 해당지역을 벗어나는 편이 안전할 수 있습니다. 셋째 본인 명의와 관련된 각종 개인정보 유출사고 소식에 관심을 가지고 주요 정보(주민번호, 통신가입정보 등)가 유출되었다는 소식을 들으면 필요한 경우 명의 도용 방지서비스나 신용정보 모니터링을 신청해 두는 것이 도움이 됩니다. 해커는 여러 경로로 얻은 정보들을 조합하여 범죄에 악용하기 때문에 내 정보가 유출된 적이 있는지 수시로 확인하는 습관이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이번 KT 펨토셀 유령기지국 해킹사건은 첨단 통신 인프라의 허점을 노린 신종 수법으로서 우리에게 두 가지 교훈을 주었습니다. 하나는 편의를 위한 기술도 보안이 담보되지 않으면 양날의 검이 될 수 있다는 점입니다. 집 안 신호 개선을 위해 보급된 펨토셀이 오히려 해커의 수중에서 통신망을 장악하는 도구가 될 수 있었듯이 모든 ICT 기술에는 보안 강화는 필수적입니다. 둘째는 통신사와 정부의 신속한 대응체계 구축입니다. 이번 사건을 통해 관계 기관들은 비로소 유령기지국 공격이라는 현실화된 위협에 눈뜨게 되었습니다. 다행히 추가 피해를 막기 위한 조치들이 빠르게 취해졌고 피해보상과 재발 방지책이 마련되고 있지만 사후 대응보다 사전 예방과 상시 모니터링 강화가 더욱 중요할 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;일반 사용자 입장에서는 눈에 보이지 않는 통신망 해킹이 막연하고 두려울 수 있습니다. 그러나 한편으로는 이러한 사건을 계기로 통신사들의 보안 의식 높아지고 시스템이 개선되는 효과도 기대할 수 있습니다. 우리는 개인차원에서 보안수칙을 잘 지키고 이상 징후에 주의를 기울이는 한편 더 큰 틀에서는 통신 인프라 전반의 보안 수준 재고를 꾸준히 요구해야겠습니다. 유령기지국의 침입을 막아낼 탄탄한 망 보안 체계 구축이 이루어질 때 비로소 안심하고 편리한 통신서비스를 누릴 수 있을 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>ars인증</category>
      <category>IMSI</category>
      <category>소액결제</category>
      <category>유령기지국</category>
      <category>정보유출</category>
      <category>초소형기지국</category>
      <category>통신보안</category>
      <category>통신해킹</category>
      <category>펨토셀</category>
      <category>해킹사고</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/550</guid>
      <comments>https://odinbox.tistory.com/550#entry550comment</comments>
      <pubDate>Sat, 13 Sep 2025 20:23:58 +0900</pubDate>
    </item>
    <item>
      <title>개발자들의 웃픈 일상, 코드 짜며 웃고 우는 이야기</title>
      <link>https://odinbox.tistory.com/549</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;ldquo;저는 HTML로 코딩하는 걸 제일 좋아합니다!&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;font-weight: normal; position: relative; line-height: 40px; background: #007CBA; border: 1px solid #fff; padding: 10px; color: white; border-radius: 0 10px 0 10px; box-shadow: inset 0 0 5px rgba(53,86,129, 0.5); font-family: 'Muli', sans-serif; border-style: solid; border-width: 0px  0px  1px 15px; border-color: #232323; background-color: #007cba;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;개발자는 커피로 코딩한다, 웃픈 밈 모음 ZIP&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd4vhp/btsQfDM3vq9/c3iFZPIL8fLEvY4RNK3290/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd4vhp/btsQfDM3vq9/c3iFZPIL8fLEvY4RNK3290/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd4vhp/btsQfDM3vq9/c3iFZPIL8fLEvY4RNK3290/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd4vhp%2FbtsQfDM3vq9%2Fc3iFZPIL8fLEvY4RNK3290%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자들은 왜 모니터 앞에서 혼자 피식피식 웃고 있을까요? 알고 보면 그 뒤엔 개발자만의 유머와 밈이 숨어 있습니다. 어려운 코드를 붙들고 씨름하다 보면, 어느새 웃픈 상황들이 펼쳐지죠. 이 글에서는 개발자들의 현실에서 탄생한 유머, 밈, 은어들을 한데 모아 소개합니다. IT나 스타트업 문화를 잘 모르는 분들도 함께 웃을 수 있도록, 하나하나 쉽고 재미있게 풀어 볼게요!&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-style: solid; font-weight: bold; border-width: 1px  1px  1px 5px; border-color: #707070; background-color: #fff; padding: 10px;&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	$(&quot;#toc&quot;).toc( {content: &quot;.tt_article_useless_p_margin&quot;, headings: &quot;h1,h2,h3,h4&quot; , top: -90, isBlink : true, blinkColor : '#21B9DE' } ) });
&lt;/script&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;개발자밈&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개발자 유머와 밈 : 용어부터 변명까지&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자들에겐 일반인에겐 낯선 용어와 드립이 있습니다. 예를 들어 프로그램을 설치할 땐 &amp;ldquo;깔았다&amp;rdquo;, 지울 땐 &amp;ldquo;밀었다&amp;rdquo;라고도 하고, 프로세스를 종료시킬 땐 과격하게 &amp;ldquo;죽인다&amp;rdquo;, 다시 실행하면 &amp;ldquo;살린다&amp;rdquo;는 표현을 씁니다. 복사해서 붙여넣기는 &amp;ldquo;갖다 붙이기&amp;rdquo;, 콘솔에 메시지를 출력하는 건 &amp;ldquo;뿌리기&amp;rdquo;처럼 말이죠. 이렇게 독특한 개발자 용어부터 벌써 웃음이 솔솔 나오나요?&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자들의 대표적인 변명 밈도 빼놓을 수 없습니다. 그중 하나가 &amp;ldquo;버그가 아니라 기능입니다&amp;rdquo;라는 말인데요. 원래 프로그램에서 예&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;상치 못한 이상 행동이 나타나면 보통 버그라고 부르지만, 개발자들은 농담 삼아 &amp;ldquo;그거 버그 아니고 원래 그런 기능이에요!&amp;rdquo; 하고 둘러대곤 합니다. 의도하지 않은 오류도 마치 계획된 기능인 척 우기는 이 유머는 전 세계 개발자들이 공감하는 관용구가 되었죠. 사용자나 상사가 &amp;ldquo;이거 왜 이래요?&amp;rdquo; 물을 때 &amp;ldquo;원래 그런 기능&amp;rdquo;이라고 뻔뻔하게 답하는 모습, 상상만 해도 웃프죠?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;또 하나, 개발자들의 단골 레퍼토리 변명 : &amp;ldquo;내 컴퓨터에서는 잘 되는데요?&amp;rdquo;입니다. 이 말도 세계 공용 개발자 밈으로 악명 높아요. 어디선가 프로그램이 에러가 났다 하면, 담당 개발자가 &amp;ldquo;이상하네요, 제 PC에선 문제없이 돌아갔는데요???&amp;rdquo; 하고 답하는 장면이 떠오릅니다. 사실 이 멘트의 속뜻은 대개 &amp;ldquo;다른 환경에서 왜 안 되는지 더 알아봐야겠네요&amp;rdquo;라는 의미지만, 듣는 사람 입장에선 &amp;ldquo;네 컴퓨터 말고 내 컴퓨터에서 돌아가야지!&amp;rdquo; 하고 속 터질 노릇이죠. 그래서 이 &amp;ldquo;Works on my machine&amp;rdquo; 변명은 아이가 입 주위에 초콜릿 잔뜩 묻히고 &amp;ldquo;전 안 먹었어요&amp;rdquo; 하는 격이라는 우스갯소리도 있습니다. 한마디로 &amp;ldquo;내 잘못 아냐~ 나는 문제없어&amp;rdquo;라는 개발자판 무죄 주장인 셈이죠.&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;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7UBlI/btsQf9LMP3Y/BefDsSptJLdDWVK3kTktlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7UBlI/btsQf9LMP3Y/BefDsSptJLdDWVK3kTktlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7UBlI/btsQf9LMP3Y/BefDsSptJLdDWVK3kTktlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7UBlI%2FbtsQf9LMP3Y%2FBefDsSptJLdDWVK3kTktlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;536&quot; height=&quot;536&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;그리고 &amp;ldquo;이게 안 되네&amp;hellip; 어, 이게 되네?&amp;rdquo;라는 유명한 밈도 있습니다. 처음엔 코드가 안 돌아가서 절망하다가, 갑자기 뚝딱 돼버리면 개발자는 어리둥절한 기쁨을 느끼는데요. 그 순간을 묘사한 유행어가 바로 &amp;ldquo;이게 안 되네? 이게 되네&amp;hellip;?&amp;rdquo;랍니다. 원래는 한 모바일 게임 캐릭터의 대사에서 유래했는데, 이제는 &amp;ldquo;엉망인 코드가 이상하게도 의도한 대로 동작할 때&amp;rdquo;나 &amp;ldquo;새내기 개발자가 어설프게 짠 코드가 돌아갈 때&amp;rdquo; 쓰이는 대표 밈이 되었죠. 한 번쯤 그런 황당한 경험, 모든 개발자가 해봤을 거예요!&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/zLZBunxh80U?si=ds1tTZzSuVMLC_R1&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;코딩하는 일상, 커피와 버그로 밤새는 개발자&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;ldquo;프로그래머는 커피를 코드로 변환하는 기계&amp;rdquo;라는 말이 있을 정도로, 커피와 개발자는 떼려야 뗄 수 없습니다. 실제로 많은 개발자들이 진한 카페인에 의존해 코딩을 이어 가곤 하죠. 밤샘 코딩이나 촉박한 마감일(데드라인)에 쫓길 때, 개발자의 책상에는 식은 커피 컵이 여러 개 쌓여있는 진풍경이 펼쳐집니다. 카페인=연료, 코드=산출물 공식이 성립하는 순간이죠.&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;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kjidj/btsQfzRubOV/tZMS6KzGQHu3k66m9vWPa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kjidj/btsQfzRubOV/tZMS6KzGQHu3k66m9vWPa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kjidj/btsQfzRubOV/tZMS6KzGQHu3k66m9vWPa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKjidj%2FbtsQfzRubOV%2FtZMS6KzGQHu3k66m9vWPa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;499&quot; height=&quot;499&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;야근과 버그와의 싸움도 개발자 일상의 일부입니다. &amp;ldquo;하루에 버그 하나씩 잡다 보면 언젠간 끝나겠지&amp;rdquo; 하면서도, 잡은 버그가 도망가면 또 잡고&amp;hellip; 마치 두더지 잡기 게임 같은 날들이 이어지죠. 그래서 탄생한 밈&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 &amp;ldquo;99 little bugs in the code, fix one bug, 127 little bugs in the code&amp;hellip;&amp;rdquo; 같은 개발자 노래(?)입니다. 버그 하나 고치면 새로운 버그 둘이 생겨나는 웃픈 상황을 노래 가사 패러디로 만든 거예요. 문제를 해결했나 싶으면 또 다른 에러 로그가 빨간 글씨로 뜨고&amp;hellip; 이런 순간에 개발자들은 웃프면서도 공감의 탄식을 내뱉습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;디버깅도 개발자의 숙명인데요. 혹시 개발자가 책상에 노란 고무 오리를 올려두고 중얼거리는 모습을 본다면 놀라지 마세요. 이것은 유명한 &amp;ldquo;러버덕 디버깅&amp;rdquo; 기법입니다. 고무 오리에게 문제를 설명하듯 하나하나 코드를 말로 풀다 보면 머릿속이 정리되어 버그를 찾게 된다는 원리죠. 실제로 많은 개발자가 인형에게 코드 설명하기로 막힌 문제를 풀곤 합니다. 남들이 보면 웃긴 장면이지만, 당사자에겐 꽤 효과적인 진지한 방법이니 이해해 주세요!&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;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8WmeV/btsQgubfiqy/p5TyJKGCEtZOgnDknbMKk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8WmeV/btsQgubfiqy/p5TyJKGCEtZOgnDknbMKk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8WmeV/btsQgubfiqy/p5TyJKGCEtZOgnDknbMKk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8WmeV%2FbtsQgubfiqy%2Fp5TyJKGCEtZOgnDknbMKk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;571&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;밤을 새워 코딩하다 보면 다크서클은 내려오고, 눈은 빨개지고&amp;hellip; 그러다 아침에 결국 에러 원인을 찾았을 때의 희열은 말로 못 합니다. 개발자 문화에서는 이런 야근 영웅담도 자주 공유되죠. 하지만 현실에선 건강이 최우선! 농담처럼 &amp;ldquo;야근이 죄는 아니잖아, 버그가 죄지&amp;rdquo;라고들 하지만, 버그 잡느라 자기 건강 버그나 만들지 말자고요.??&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;회의보다 이메일 : 개발자들의 소통법&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자 유머 중엔 회의에 대한 쓴소리(?)도 있습니다. 그 대표적인 말이 &amp;ldquo;이 회의는 이메일 한 통으로 충분했는데&amp;rdquo;일 거예요. 필요한 정보 몇 줄 주고받으면 될 일을 굳이 모두 불러 모아 긴 회의를 할 때, 개발자들은 속으로 이렇게 외칩니다 : &amp;ldquo;차라리 그 시간에 코딩 몇 줄 더 치겠다!&amp;rdquo; 공감 가시나요?&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;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exSmWF/btsQemZw3YO/TIe1SnlYeeBw8jgTkxGJi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exSmWF/btsQemZw3YO/TIe1SnlYeeBw8jgTkxGJi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exSmWF/btsQemZw3YO/TIe1SnlYeeBw8jgTkxGJi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FexSmWF%2FbtsQemZw3YO%2FTIe1SnlYeeBw8jgTkxGJi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;475&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;특히 긴 회의나 불필요한 보고 시간은 개발자들이 가장 답답해하는 순간 중 하나입니다. 하루에도 수십 번 머릿속으로 코드 구조를 그려보는 사람들이라, 불필요하게 느껴지는 회의에서는 딴생각&amp;hellip; 예컨대 버그 해결 방안이나 다음에 짤 밈 생각에 빠지기 일쑤죠. 그래서 생긴 밈이 회의 시간에 노트북으로 코딩하는 만화라든가, 회의 중 졸려하는 개발자 짤방 등입니다. 물론 모든 회의가 나쁜 건 아니지만, 개발자들은 효율과 집중을 중시하기 때문에 쓸데없이 긴 회의는 유머의 대상이 되곤 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자들의 소통은 때로 비대면이나 텍스트에 강한 경향도 있습니다. 이메일이나 슬랙(Slack) 같은 협업툴로 요점을 공유하고 바로 코딩으로 돌입하는 걸 선호하죠. 그래서 팀 메신저 대화방엔 업무 얘기 옆에 귀여운 밈 GIF들이 종종 올라옵니다. 예컨대 누가 밤새 버그를 잡았다면 동료가 &amp;lsquo;슈퍼히어로 밈 GIF&amp;rsquo;를 올려주거나, 금요일 오후 배포를 강행한다고 하면 &amp;lsquo;멈춰!&amp;rsquo; 밈 이미지로 말리는 식이죠. 이런 짤 문화 덕에 딱딱한 개발 업무도 한결 인간미 넘치고 웃음이 오갑니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;한편 개발자들은 데일리 스탠드업 미팅(매일 아침 짧게 진행 상황 공유하는 회의)도 하는데, 여기에 얽힌 농담도 있어요. 일부 개발자는 어제 한 일을 그대로 복붙 해서 오늘도 했다고 보고하거나, &amp;ldquo;어제도 버그 잡았고 오늘도 버그 잡을 예정입니다. 이상입니다.&amp;rdquo;처럼 짧게 끝내죠. 이런 모습을 두고 &amp;ldquo;역시 코드를 줄이는 사람들답게 보고도 최소화!&amp;rdquo;라며 농담합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;개발자 문화와 밈 : 함께 웃는 커뮤니티&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;전 세계 개발자들은 커뮤니티를 통해 밈을 공유하며 하나의 문화를 이뤘습니다. 특히 레딧(Reddit)의 ProgrammerHumor 게시판이나 트위터(X)의 개발자 계정들, 깃허브 저장소 등에는 개발자 밈의 원천이 넘쳐납니다. 예를 들어, 흔히들 &amp;ldquo;스택 오버플로우 없인 코딩을 못 해&amp;rdquo;라고들 하는데, 스택 오버플로우(Stack Overflow)는 개발 Q&amp;amp;ampA 커뮤니티죠. 여기서 답변 코드를 복사해다 붙이는 일이 워낙 흔해지다 보니, 스스로를 &amp;ldquo;풀스택 개발자&amp;rdquo; 대신 &amp;ldquo;풀-스택오버플로우 개발자&amp;rdquo;라고 자조하는 농담까지 생겼습니다. 즉 모든 걸 다 할 줄 아는 척하지만 사실 모르면 커뮤니티에 물어봐서 해결한다는 웃픈 고백이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;또 다른 밈 전쟁의 역사로 &amp;ldquo;탭 vs 스페이스&amp;rdquo; 논쟁이 있어요. 코드를 들여 쓰기 할 때 탭(tab)을 쓰느냐 스페이스(space) 4번을 쓰느냐는 개발자들 사이 오랜 holy war(성전)인데요, 사실 결과는 똑같으면서도 누구도 양보 못 하는 우스운 싸움이죠. 심지어 이걸 주제로 한 코미디 단편 영화까지 있을 정도예요 (개발자 두 명이 취조실에서 &amp;ldquo;당신 탭 썼지? 자백해!&amp;rdquo; 뭐 이런 내용의??). 물론 실제로는 각자 취향 차이지만, 이런 사소한 것으로 친목 겸 드립을 치는 문화가 재밌는 겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;다크 모드 사랑도 개발자 문화의 밈 중 하나입니다. 많은 개발자가 IDE나 에디터 화면을 검은 배경(다크 모드)으로 쓰는데, 이유를 묻는 농담에 이렇게 답하곤 하죠 : &amp;ldquo;프로그래머들이 다크 모드를 선호하는 이유? 밝은 화면은 벌레(버그)를 끌어당기니까!&amp;rdquo;??(영어로 bug는 벌레라는 뜻도 있으니까요). 밝은 화면 쓰면 버그 생긴다는 억지 같지만 그만큼 어둠을 사랑하는 개발자들의 심정을 유머러스하게 표현한 겁니다. 실제로 &amp;ldquo;라이트 모드(흰 화면) 쓰는 개발자는 사이코패스&amp;rdquo;라는 농담이 있을 정도로, 다크 모드 선호는 절&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;대적이죠. (짤 : 눈이 부신 하얀 화면을 보고 경악하는 개발자 표정의 밈) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자들은 자신을 놀리는 밈에도 꽤 관대합니다. 왜냐하면 요즘 개발자는 사회적으로 인기 있고 대접받는 직종이라서, 밈으로 희화화되어도 약자에 대한 비하처럼 느끼지 않기 때문이라는 분석도 있어요. 실제 한 개발자 블로거는 &amp;ldquo;개발자가 다른 직군에 비해 취약계층이 아니기 때문에, 개발자 밈을 보며 여유롭게 웃을 수 있는 것&amp;rdquo;이라고 하더군요. 쉽게 말해, 연봉도 높고 대우도 좋으니 밈 소재가 돼도 마음 편하다는 거죠. 그래서 자기 비하 개그도 즐기고, 동료끼리 &amp;ldquo;우리 다 같이 정신 나갔지 헤헤&amp;rdquo; 하며 웃어넘기는 문화가 형성되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;마지막으로, 개발자 문화의 꽃인 밈 공유는 공감과 위로의 역할도 합니다. 프로젝트 폭망 이야기를 밈으로 만들면 &amp;ldquo;우리만 그런 게 아니구나&amp;rdquo; 안심이 되고, 신기술에 쫓겨 허덕이는 일상을 웹툰으로 보면 서로 킥킥대며 스트레스를 날려버리죠. GitHub 잔디밭(커밋 기록) 자랑이나, 배포 후 서버 터졌을 때의 심정 등을 다룬 짤방들도 웃음을 줍니다. 심지어 개발자 전용 이모티콘이나 밈 스티커도 등장해서, 메신저에서 &amp;ldquo;버그 발견!&amp;rdquo; 하면 귀여운 벌레 캐릭터 이모티콘을 쓰고, &amp;ldquo;퇴근 언제?&amp;rdquo;에는 팬더가 눈물 흘리는 짤을 보내기도 해요. 이렇듯 개발자들의 유머는 그들만의 문화이자 하루를 버티게 해주는 활력소가 되고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;마무리&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;여기까지 살펴본 개발자들의 유머 코드, 재미있으셨나요??? 비 개발자라도 이해할 수 있도록 풀어낸다고 했지만, 혹시 &amp;ldquo;무슨 소리야?&amp;rdquo; 싶은 부분도 있었을지 모르겠습니다. 그래도 한 가지 분명한 건, 개발자들도 우리와 똑같이 웃고 운다는 것이에요. 버그 앞에서 속상해하다가도 밈 하나에 허탈한 웃음을 짓고, 야근으로 녹초가 되어도 동료의 농담 한 방에 피식 힘을 얻고&amp;hellip; 이렇게 웃픈 순간들을 나누며 같이 성장하는게&amp;nbsp;개발자 문화의 매력 아닐까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자는 늘 새로운 문제를 마주하지만, 그럴 때마다 유머 감각을 장착하고 &amp;ldquo;버그 따위 우습지!&amp;rdquo; 넘길 줄 아는 멋진 사람들입니다. 오늘 소개한 밈들과 이야기들로 잠시나마 웃음을 드렸길 바라면서, 글을 마칩니다. 코드를 짤 땐 진지하게, 그러나 웃음 버튼도 곁에 장&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&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;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bubaVQ/btsQggKTHPc/xmlPcnoK0dYMOtUYUwVQdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bubaVQ/btsQggKTHPc/xmlPcnoK0dYMOtUYUwVQdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bubaVQ/btsQggKTHPc/xmlPcnoK0dYMOtUYUwVQdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbubaVQ%2FbtsQggKTHPc%2FxmlPcnoK0dYMOtUYUwVQdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;377&quot; height=&quot;377&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;AI가 이미지까지 척척 만들어주니까, 이제 제 생각은 단순합니다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;ldquo;AI야, 코드도 대신 짜줄래?&amp;rdquo; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;... 네, 맞습니다. 오늘도 회사 일 하기 싫다는 뜻입니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT</category>
      <category>IT유머</category>
      <category>개발자</category>
      <category>개발자문화</category>
      <category>개발자밈</category>
      <category>버그</category>
      <category>스타트업</category>
      <category>야근</category>
      <category>엔지니어</category>
      <category>코딩</category>
      <category>프로그래밍</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/549</guid>
      <comments>https://odinbox.tistory.com/549#entry549comment</comments>
      <pubDate>Sat, 6 Sep 2025 08:04:00 +0900</pubDate>
    </item>
    <item>
      <title>개발자와 직장인을 위한 효과적인 시간 관리 전략</title>
      <link>https://odinbox.tistory.com/548</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 하면 좋지 않을까라는 생각으로 적어본 글&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;font-weight: normal; position: relative; line-height: 40px; background: #007CBA; border: 1px solid #fff; padding: 10px; color: white; border-radius: 0 10px 0 10px; box-shadow: inset 0 0 5px rgba(53,86,129, 0.5); font-family: 'Muli', sans-serif; border-style: solid; border-width: 0px  0px  1px 15px; border-color: #232323; background-color: #007cba;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;개발자(직장인)의 시간은 어떻게 관리되어야 하는가, 생산성을 높이는 집중 및 우선순위&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (8).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eCZ6TF/btsQfAJqp9v/022kGMEk2qGPwaYAumAbyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eCZ6TF/btsQfAJqp9v/022kGMEk2qGPwaYAumAbyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eCZ6TF/btsQfAJqp9v/022kGMEk2qGPwaYAumAbyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeCZ6TF%2FbtsQfAJqp9v%2F022kGMEk2qGPwaYAumAbyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (8).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;실무&amp;nbsp;현장에서&amp;nbsp;우리는&amp;nbsp;언제나&amp;nbsp;한정된&amp;nbsp;시간&amp;nbsp;안에&amp;nbsp;무수한&amp;nbsp;일을&amp;nbsp;처리해야&amp;nbsp;하는&amp;nbsp;압박감&amp;nbsp;속에&amp;nbsp;살아갑니다.&amp;nbsp;하루는&amp;nbsp;고작&amp;nbsp;24시간뿐인데,&amp;nbsp;회의와&amp;nbsp;보고,&amp;nbsp;개발과&amp;nbsp;버그&amp;nbsp;수정,&amp;nbsp;팀&amp;nbsp;소통과&amp;nbsp;개인&amp;nbsp;업무까지&amp;nbsp;동시에&amp;nbsp;몰려옵니다.&amp;nbsp;그러다&amp;nbsp;보면&amp;nbsp;정말&amp;nbsp;중요한&amp;nbsp;일에&amp;nbsp;집중하기보다는&amp;nbsp;눈앞의&amp;nbsp;급한&amp;nbsp;일만&amp;nbsp;처리하다&amp;nbsp;하루가&amp;nbsp;끝나버리기&amp;nbsp;일쑤입니다.&amp;nbsp;저&amp;nbsp;역시&amp;nbsp;개발&amp;nbsp;업무를&amp;nbsp;하면서&amp;nbsp;&amp;ldquo;어떻게&amp;nbsp;하면&amp;nbsp;제한된&amp;nbsp;시간을&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;효율적으로&amp;nbsp;활용할&amp;nbsp;수&amp;nbsp;있을까?&amp;rdquo;라는&amp;nbsp;고민을&amp;nbsp;끊임없이&amp;nbsp;해왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이런&amp;nbsp;고민&amp;nbsp;속에서&amp;nbsp;발견한&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;실질적인&amp;nbsp;방법이&amp;nbsp;있습니다.&amp;nbsp;대표적으로는&amp;nbsp;Eisenhower&amp;nbsp;매트릭스를&amp;nbsp;활용한&amp;nbsp;우선순위&amp;nbsp;설정,&amp;nbsp;Cal&amp;nbsp;Newport가&amp;nbsp;제안한&amp;nbsp;시간&amp;nbsp;블록&amp;nbsp;관리(Time&amp;nbsp;Blocking)&amp;nbsp;기법,&amp;nbsp;그리고&amp;nbsp;다중작업을&amp;nbsp;줄이고&amp;nbsp;단일작업(싱글태스킹)에&amp;nbsp;집중하는&amp;nbsp;습관입니다.&amp;nbsp;이&amp;nbsp;세&amp;nbsp;가지는&amp;nbsp;단순한&amp;nbsp;이론이&amp;nbsp;아니라,&amp;nbsp;실제로&amp;nbsp;바쁜&amp;nbsp;개발자나&amp;nbsp;직장인들이&amp;nbsp;분주한&amp;nbsp;일상&amp;nbsp;속에서도&amp;nbsp;본질적인&amp;nbsp;업무에&amp;nbsp;몰입할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;돕는&amp;nbsp;매우&amp;nbsp;강력한&amp;nbsp;도구입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;결국&amp;nbsp;제가&amp;nbsp;정리하고&amp;nbsp;싶은&amp;nbsp;고민의&amp;nbsp;핵심은&amp;nbsp;이것입니다.&amp;nbsp;&amp;ldquo;수많은&amp;nbsp;업무와&amp;nbsp;방해&amp;nbsp;요인&amp;nbsp;속에서&amp;nbsp;어떻게&amp;nbsp;하면&amp;nbsp;내가&amp;nbsp;진짜&amp;nbsp;중요한&amp;nbsp;일에&amp;nbsp;시간을&amp;nbsp;쓸&amp;nbsp;수&amp;nbsp;있을까?&amp;rdquo;&amp;nbsp;이&amp;nbsp;질문에&amp;nbsp;답을&amp;nbsp;찾는&amp;nbsp;과정에서&amp;nbsp;배운&amp;nbsp;원칙들을&amp;nbsp;이번&amp;nbsp;글에서&amp;nbsp;풀어내고자&amp;nbsp;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-style: solid; font-weight: bold; border-width: 1px  1px  1px 5px; border-color: #707070; background-color: #fff; padding: 10px;&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	$(&quot;#toc&quot;).toc( {content: &quot;.tt_article_useless_p_margin&quot;, headings: &quot;h1,h2,h3,h4&quot; , top: -90, isBlink : true, blinkColor : '#21B9DE' } ) });
&lt;/script&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;시간관리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;들어가기 전&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;아침에 업무를 시작하며 가장 중요한 프로젝트를 머릿속에 그려보지만 컴퓨터를 켜는 순간 이메일과 메신저 알림이 쏟아집니다. 급하게 온 요청들을 처리하고 나니 곧 회의 시간입니다. 회의 도중에도 추가 업무 지시와 긴급 문의가 이어지고 정작 오늘 꼭 진척을 내야 할 중요한 작업은 손도 대지 못한 채 하루가 끝나버립니다. 이러한 경험은 많은 개발자와 직장인들에겐 낯설지 않을 겁니다. 실제로 스티븐 코비는 &quot;대부분의 사람들은 긴급한 일에 쫓기느라 정작 중요한 일에는 충분한 시간을 들이지 못한다&quot;라고 지적했습니다. 현대 사회에서 시간 관리는 개인의 생산성과 삶의 질을 결정하는 핵심 역량이며 우리가 한정된 시간의 주인이 되지 못하면 일에 끌려다니는 삶을 벗어나기 어렵습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;최근 IT 리더 Mike Fisher[&lt;a title=&quot;Mike Fisher&quot; href=&quot;https://mikefisher.substack.com/p/time-management&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#&lt;/a&gt;]님이 올리셨던 글을 참고하여 &quot;10 Ways to Take Ownership of Your Time&quot;에서 이러한 시간 관리 문제를 해결하기 위한 10가지 기법을 소개했습니다. 그 핵심은 시간의 주도권을 되찾아 중요한 목표에 우리의 시간을 투자하는 것입니다. 시간관리에 대해서 어떤 유용한 원칙들이 있는지 살펴보고 이야기해보려고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;긴급함에 쫓기지 말고, 중요한 일에 집중하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;1139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OtLtn/btsQfflhUiF/mOATzuk0lDpokmm22KfHj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OtLtn/btsQfflhUiF/mOATzuk0lDpokmm22KfHj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OtLtn/btsQfflhUiF/mOATzuk0lDpokmm22KfHj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOtLtn%2FbtsQfflhUiF%2FmOATzuk0lDpokmm22KfHj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1648&quot; height=&quot;1139&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;1139&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;업무를 하다 보면 눈앞의 긴급한 일들이 끊임없이 나타나 우리를 몰아붙입니다. 그러나 긴급한 일이 항상 중요한 일은 아닙니다. 폭풍처럼 밀려드는 요청에 일일이 대응하다 보면 정작 장기적으로 큰 가치와 성과를 내는 중요한 일은 뒤로 밀리기 쉽습니다. 이를 극복하기 위해 아이젠하워 중요-긴급 매트릭스(EisenhowerMatrix)가 유용합니다. 아이젠하워 매트릭스는 해야 할 업무를 중요도와 긴급도 축으로 분류하여 4개 사분면에 배치하는 도구로서 긴급성과 중요성을 하눈에 평가하도록 돕습니다. 이를 통해 우리는 업무의 우선순위를 재정립하고 무턱대고 모든 일에 쫓기는 악순환에서 벗어날 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;예를 들어 팀 리드로 일한다고 하면 갑작스러운 버그 수정 요청이나 사소한 문의(긴급하지만 중요다가 낮은 일)에 즉각 매달리기보다 하루 중 우선 중요하고 긴급한 일(예를 들어 마감 임박한 핵심 기능 구현)부터 처리하려고 노력하는 등 긴급하지는 않지만 성장과 목표 달성에 중요한 일(예를 들어 기술 부채 개선이나 전력 기획 등)은 별도로 시간을 확보해 수행 일정에 넣었습니다. 반면 긴급해 보이나 팀의 목표와 관련이 적은 업무는 과감히 위임하거나 일정을 재조정했고 중요도도 낮고 긴급하지 않은 일들은 생략하거나 최소화했습니다. 이렇게 업무를 분류하고 나니 하루가 끝날 때 정말로 가치 있는&amp;nbsp; 성과가 남는 날이 점저 늘어날 수 있는 상황이 늘어납니다. 실제 하버드대 커리어 전문가 Gorickng도 이 매트릭스를 활용하면 일의 홍수 속에서 무엇을 먼저 해야 할지 구분할 수 있고 정기적으로 이 분류를 재점검하면 자신의 목표와 가치에 가장 의미 있는 곳에서 시간을 쓸 수 있게 된다고 합니다. 결국 긴급함에 휘둘리지 않고 중요한 일을 우선하는 원칙이 시간 관리의 출발점이라 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;하루를 설계하는 시간 블록 관리 전략&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dyUK8i/btsQfwG4Xs1/lqPVeh065llV4CsIpDOaUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dyUK8i/btsQfwG4Xs1/lqPVeh065llV4CsIpDOaUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dyUK8i/btsQfwG4Xs1/lqPVeh065llV4CsIpDOaUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdyUK8i%2FbtsQfwG4Xs1%2FlqPVeh065llV4CsIpDOaUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;498&quot; height=&quot;498&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;개발자들은&amp;nbsp;회의,&amp;nbsp;코딩,&amp;nbsp;코드&amp;nbsp;리뷰,&amp;nbsp;버그&amp;nbsp;대응&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;작업&amp;nbsp;유형을&amp;nbsp;하루&amp;nbsp;동안&amp;nbsp;수행합니다.&amp;nbsp;이때&amp;nbsp;시간&amp;nbsp;블록&amp;nbsp;관리(Time&amp;nbsp;Blocking)&amp;nbsp;기법을&amp;nbsp;활용하면&amp;nbsp;산만한&amp;nbsp;일정을&amp;nbsp;체계적으로&amp;nbsp;조직할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;시간&amp;nbsp;블록&amp;nbsp;관리란&amp;nbsp;말&amp;nbsp;그대로&amp;nbsp;하루를&amp;nbsp;여러&amp;nbsp;블록으로&amp;nbsp;나누고&amp;nbsp;각&amp;nbsp;블록에&amp;nbsp;특정&amp;nbsp;업무를&amp;nbsp;할당하는&amp;nbsp;방식입니다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;필자는&amp;nbsp;오전&amp;nbsp;시간을&amp;nbsp;2~3시간짜리&amp;nbsp;코딩&amp;nbsp;집중&amp;nbsp;블록으로&amp;nbsp;정해두고,&amp;nbsp;이&amp;nbsp;시간만큼은&amp;nbsp;다른&amp;nbsp;회의나&amp;nbsp;메신저&amp;nbsp;확인을&amp;nbsp;최대한&amp;nbsp;배제합니다.&amp;nbsp;점심&amp;nbsp;이후&amp;nbsp;한두&amp;nbsp;시간은&amp;nbsp;동료와&amp;nbsp;토론하거나&amp;nbsp;코드&amp;nbsp;리뷰를&amp;nbsp;하는&amp;nbsp;커뮤니케이션&amp;nbsp;블록으로&amp;nbsp;사용하고,&amp;nbsp;남은&amp;nbsp;시간은&amp;nbsp;이메일&amp;nbsp;정리나&amp;nbsp;잡무를&amp;nbsp;처리하는&amp;nbsp;시간으로&amp;nbsp;배분합니다.&amp;nbsp;이렇게&amp;nbsp;일정을&amp;nbsp;설계해&amp;nbsp;두면&amp;nbsp;예기치&amp;nbsp;못한&amp;nbsp;일이&amp;nbsp;생겨도&amp;nbsp;큰&amp;nbsp;틀에서&amp;nbsp;우선순위&amp;nbsp;있는&amp;nbsp;업무에&amp;nbsp;충분한&amp;nbsp;시간을&amp;nbsp;확보할&amp;nbsp;수&amp;nbsp;있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;시간&amp;nbsp;블로킹&amp;nbsp;기법을&amp;nbsp;대중화한&amp;nbsp;Cal&amp;nbsp;Newport는&amp;nbsp;일정표를&amp;nbsp;빈&amp;nbsp;달력이&amp;nbsp;아니라&amp;nbsp;해야&amp;nbsp;할&amp;nbsp;일을&amp;nbsp;담는&amp;nbsp;시간&amp;nbsp;예산서로&amp;nbsp;활용하라고&amp;nbsp;조언합니다.&amp;nbsp;위&amp;nbsp;그림처럼&amp;nbsp;하루를&amp;nbsp;미리&amp;nbsp;설계해 두면&amp;nbsp;마치&amp;nbsp;회의&amp;nbsp;일정을&amp;nbsp;지키듯&amp;nbsp;자신과의&amp;nbsp;약속을&amp;nbsp;지키게&amp;nbsp;되어,&amp;nbsp;중요한&amp;nbsp;업무를&amp;nbsp;몰입할&amp;nbsp;시간을&amp;nbsp;확보하게&amp;nbsp;됩니다.&amp;nbsp;업무&amp;nbsp;특성상&amp;nbsp;하루가&amp;nbsp;예측&amp;nbsp;불가능하게&amp;nbsp;흐를&amp;nbsp;수밖에&amp;nbsp;없는&amp;nbsp;경우에도,&amp;nbsp;최소한&amp;nbsp;필요한&amp;nbsp;만큼의&amp;nbsp;블록은&amp;nbsp;사수하려고&amp;nbsp;노력하는&amp;nbsp;것과&amp;nbsp;전혀&amp;nbsp;계획&amp;nbsp;없이&amp;nbsp;임기응변으로&amp;nbsp;임하는&amp;nbsp;것에는&amp;nbsp;큰&amp;nbsp;차이가&amp;nbsp;있음을&amp;nbsp;느꼈습니다.&amp;nbsp;한&amp;nbsp;개발팀에서는&amp;nbsp;아예&amp;nbsp;팀&amp;nbsp;공용&amp;nbsp;달력에&amp;nbsp;코딩&amp;nbsp;타임을&amp;nbsp;블록으로&amp;nbsp;설정해&amp;nbsp;두고&amp;nbsp;그&amp;nbsp;시간엔&amp;nbsp;회의를&amp;nbsp;잡지&amp;nbsp;않기로&amp;nbsp;합의하기도&amp;nbsp;했습니다.&amp;nbsp;이렇게&amp;nbsp;하면&amp;nbsp;개발자&amp;nbsp;개인뿐&amp;nbsp;아니라&amp;nbsp;팀&amp;nbsp;전체가&amp;nbsp;중요한&amp;nbsp;개발&amp;nbsp;작업에&amp;nbsp;필요한&amp;nbsp;시간을&amp;nbsp;보호할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이처럼&amp;nbsp;시간&amp;nbsp;블록&amp;nbsp;관리로&amp;nbsp;하루를&amp;nbsp;능동적으로&amp;nbsp;설계하면,&amp;nbsp;주어진&amp;nbsp;시간&amp;nbsp;내에&amp;nbsp;가장&amp;nbsp;의미&amp;nbsp;있는&amp;nbsp;일을&amp;nbsp;완료할&amp;nbsp;가능성이&amp;nbsp;훨씬&amp;nbsp;높아집니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;멀티태스킹의 함정과 한 가지 일에 집중하는 힘&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;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctot38/btsQdxOkebw/k7hILaUYGK1N1z2cKqYCT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctot38/btsQdxOkebw/k7hILaUYGK1N1z2cKqYCT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctot38/btsQdxOkebw/k7hILaUYGK1N1z2cKqYCT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fctot38%2FbtsQdxOkebw%2Fk7hILaUYGK1N1z2cKqYCT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;515&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;업무 효율을 높이려고 여러 가지 일을 동시에 처리(멀티태스킹)하는 사람들이 많지만, 아이러니하게도 이는 생산성을 떨어뜨리는 주범입니다. 한 연구에 따르면 멀티태스킹을 많이 하는 사람들은 한 번에 하나씩 차례로 처리하는 사람들보다 업무 효율이 낮고, 일단 작업 흐름이 끊기면 다시 집중력을 되찾는 데 평균 23분 15초가 걸린다고 합니다. 결국 동시에 여러 일을 해내려는 욕심이 오히려 시간을 낭비시키고 두뇌의 에너지만 소모하는 셈입니다. 필자 역시 한때는 IDE로 코드를 작성하면서 옆 화면으로 이메일 알림을 수시로 확인하고, 전화 통화까지 하며 다중작업을 자처했던 적이 있습니다. 그러나 결과를 돌이켜보면 그런 날은 잦은 문맥 전환 때문에 정말 중요한 코드 한 줄 제대로 작성하지 못한 채 피로감만 누적되곤 했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;그&amp;nbsp;이후로&amp;nbsp;업무&amp;nbsp;방식에&amp;nbsp;큰&amp;nbsp;변화를&amp;nbsp;주었습니다.&amp;nbsp;이제는&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;한&amp;nbsp;가지&amp;nbsp;업무에만&amp;nbsp;몰입하려고&amp;nbsp;의식적으로&amp;nbsp;노력합니다.&amp;nbsp;코딩할&amp;nbsp;때는&amp;nbsp;메신저와&amp;nbsp;이메일&amp;nbsp;알림을&amp;nbsp;잠시&amp;nbsp;꺼두고,&amp;nbsp;면밀한&amp;nbsp;사고가&amp;nbsp;필요한&amp;nbsp;설계&amp;nbsp;작업&amp;nbsp;시간엔&amp;nbsp;아예&amp;nbsp;사무실&amp;nbsp;메시지도&amp;nbsp;뒤로&amp;nbsp;미룹니다.&amp;nbsp;이러한&amp;nbsp;싱글태스킹&amp;nbsp;원칙을&amp;nbsp;지키면서&amp;nbsp;제&amp;nbsp;업무&amp;nbsp;완성도와&amp;nbsp;속도가&amp;nbsp;크게&amp;nbsp;향상되었습니다.&amp;nbsp;역사적으로도&amp;nbsp;위대한&amp;nbsp;성과를&amp;nbsp;낸&amp;nbsp;이들은&amp;nbsp;몰입의&amp;nbsp;가치를&amp;nbsp;강조해 왔습니다.&amp;nbsp;모차르트는&amp;nbsp;&amp;ldquo;여러&amp;nbsp;일을&amp;nbsp;빨리해 내는&amp;nbsp;지름길은&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;한&amp;nbsp;가지&amp;nbsp;일만&amp;nbsp;하는&amp;nbsp;것&amp;rdquo;이라고&amp;nbsp;말했으며,&amp;nbsp;실제로&amp;nbsp;하나의&amp;nbsp;작업에&amp;nbsp;깊이&amp;nbsp;몰입할&amp;nbsp;때&amp;nbsp;창의성과&amp;nbsp;문제&amp;nbsp;해결&amp;nbsp;능력이&amp;nbsp;최고조에&amp;nbsp;달하는&amp;nbsp;것을&amp;nbsp;느낍니다.&amp;nbsp;개발&amp;nbsp;현장에서도&amp;nbsp;집중의&amp;nbsp;힘을&amp;nbsp;높이기&amp;nbsp;위해&amp;nbsp;포모도로&amp;nbsp;기법을&amp;nbsp;활용하는&amp;nbsp;동료가&amp;nbsp;많은데,&amp;nbsp;25분간&amp;nbsp;한&amp;nbsp;가지&amp;nbsp;일에만&amp;nbsp;집중하고&amp;nbsp;5분&amp;nbsp;휴식하는&amp;nbsp;사이클을&amp;nbsp;반복하는&amp;nbsp;이&amp;nbsp;방법은&amp;nbsp;뇌가&amp;nbsp;산만해지기&amp;nbsp;전에&amp;nbsp;짧은&amp;nbsp;집중을&amp;nbsp;누적시키는&amp;nbsp;데&amp;nbsp;효과적입니다.&amp;nbsp;예컨대&amp;nbsp;저도&amp;nbsp;오전에&amp;nbsp;2~3회&amp;nbsp;포모도로를&amp;nbsp;실행하며&amp;nbsp;코딩에&amp;nbsp;몰두한&amp;nbsp;뒤,&amp;nbsp;오후에는&amp;nbsp;짧은&amp;nbsp;휴식&amp;nbsp;후&amp;nbsp;다른&amp;nbsp;업무로&amp;nbsp;전환하는&amp;nbsp;식으로&amp;nbsp;리듬을&amp;nbsp;관리하고&amp;nbsp;있습니다.&amp;nbsp;처음에는&amp;nbsp;한&amp;nbsp;가지&amp;nbsp;일에만&amp;nbsp;집중하기가&amp;nbsp;힘들지만,&amp;nbsp;연습을&amp;nbsp;통해&amp;nbsp;집중근육을&amp;nbsp;단련하면&amp;nbsp;어느새&amp;nbsp;짧은&amp;nbsp;시간에도&amp;nbsp;깊은&amp;nbsp;성과를&amp;nbsp;내는&amp;nbsp;자신을&amp;nbsp;발견하게&amp;nbsp;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;시간을 지배하는 법, 목표에 맞게 일하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MpWYW/btsQgelSRZ1/zmdfKrDCFBit6tZGXuFmx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MpWYW/btsQgelSRZ1/zmdfKrDCFBit6tZGXuFmx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MpWYW/btsQgelSRZ1/zmdfKrDCFBit6tZGXuFmx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMpWYW%2FbtsQgelSRZ1%2FzmdfKrDCFBit6tZGXuFmx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;508&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;한정된&amp;nbsp;시간&amp;nbsp;자원을&amp;nbsp;제대로&amp;nbsp;활용하려면&amp;nbsp;바쁘게&amp;nbsp;일하는&amp;nbsp;것과&amp;nbsp;잘&amp;nbsp;일하는&amp;nbsp;것을&amp;nbsp;구분해야&amp;nbsp;합니다.&amp;nbsp;앞서&amp;nbsp;살펴본&amp;nbsp;원칙들을&amp;nbsp;종합하면,&amp;nbsp;효과적인&amp;nbsp;시간&amp;nbsp;관리란&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;일을&amp;nbsp;억지로&amp;nbsp;끼워&amp;nbsp;넣는&amp;nbsp;것이&amp;nbsp;아니라&amp;nbsp;스마트하게&amp;nbsp;일하는&amp;nbsp;것입니다.&amp;nbsp;스마트하게&amp;nbsp;일한다는&amp;nbsp;것은&amp;nbsp;자신의&amp;nbsp;핵심&amp;nbsp;목표에&amp;nbsp;맞춰&amp;nbsp;시간과&amp;nbsp;에너지를&amp;nbsp;배분하는&amp;nbsp;일입니다.&amp;nbsp;개발자라면&amp;nbsp;제품의&amp;nbsp;품질&amp;nbsp;향상이나&amp;nbsp;중요한&amp;nbsp;기능&amp;nbsp;개발&amp;nbsp;같은&amp;nbsp;장기적&amp;nbsp;가치를&amp;nbsp;최우선&amp;nbsp;순위에&amp;nbsp;두고&amp;nbsp;시간을&amp;nbsp;투자해야&amp;nbsp;합니다.&amp;nbsp;창업자나&amp;nbsp;팀&amp;nbsp;리더라면&amp;nbsp;방향성을&amp;nbsp;잡는&amp;nbsp;기획과&amp;nbsp;의사결정에&amp;nbsp;충분한&amp;nbsp;시간을&amp;nbsp;할애해야&amp;nbsp;할&amp;nbsp;것입니다.&amp;nbsp;일과를&amp;nbsp;설계할&amp;nbsp;때&amp;nbsp;늘&amp;nbsp;&amp;ldquo;이&amp;nbsp;활동이&amp;nbsp;나나&amp;nbsp;우리&amp;nbsp;조직의&amp;nbsp;목표에&amp;nbsp;얼마나&amp;nbsp;이바지하는가?&amp;rdquo;를&amp;nbsp;자문해&amp;nbsp;보면,&amp;nbsp;우선순위에서&amp;nbsp;밀려나야&amp;nbsp;할&amp;nbsp;일과&amp;nbsp;집중해야&amp;nbsp;할&amp;nbsp;일이&amp;nbsp;보입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;또한&amp;nbsp;자신의&amp;nbsp;업무&amp;nbsp;스타일을&amp;nbsp;돌아보고&amp;nbsp;생산성을&amp;nbsp;높여주는&amp;nbsp;작은&amp;nbsp;습관들도&amp;nbsp;활용하면&amp;nbsp;좋습니다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;GTD와&amp;nbsp;같은&amp;nbsp;생산성&amp;nbsp;구조에서는&amp;nbsp;모든&amp;nbsp;할&amp;nbsp;일을&amp;nbsp;머릿속이&amp;nbsp;아니라&amp;nbsp;신뢰할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;시스템에&amp;nbsp;적어두고&amp;nbsp;처리&amp;nbsp;순서를&amp;nbsp;정하라고&amp;nbsp;권합니다.&amp;nbsp;저도&amp;nbsp;업무용&amp;nbsp;노트&amp;nbsp;앱에&amp;nbsp;해야&amp;nbsp;할&amp;nbsp;일들을&amp;nbsp;프로젝트별로&amp;nbsp;기록하고,&amp;nbsp;매일&amp;nbsp;아침&amp;nbsp;최우선으로&amp;nbsp;처리할&amp;nbsp;상위&amp;nbsp;3~5개&amp;nbsp;업무를&amp;nbsp;골라냅니다.&amp;nbsp;이렇게&amp;nbsp;적어두면&amp;nbsp;업무량이&amp;nbsp;많아도&amp;nbsp;머릿속이&amp;nbsp;맑게&amp;nbsp;유지되고&amp;nbsp;지금&amp;nbsp;할&amp;nbsp;일에만&amp;nbsp;전념하기&amp;nbsp;쉬워집니다.&amp;nbsp;사소한&amp;nbsp;일들이&amp;nbsp;쌓여&amp;nbsp;큰&amp;nbsp;부담이&amp;nbsp;되는&amp;nbsp;것을&amp;nbsp;막기&amp;nbsp;위해,&amp;nbsp;2분&amp;nbsp;안에&amp;nbsp;끝낼&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;작업은&amp;nbsp;바로&amp;nbsp;처리하는&amp;nbsp;&amp;ldquo;2분&amp;nbsp;규칙&amp;rdquo;도&amp;nbsp;유용합니다.&amp;nbsp;이메일&amp;nbsp;회신이나&amp;nbsp;간단한&amp;nbsp;보고처럼&amp;nbsp;짧은&amp;nbsp;업무는&amp;nbsp;곧바로&amp;nbsp;처리해 버림으로써&amp;nbsp;작업&amp;nbsp;목록을&amp;nbsp;정리하고&amp;nbsp;정신적&amp;nbsp;부담을&amp;nbsp;줄일&amp;nbsp;수&amp;nbsp;있었습니다.&amp;nbsp;반대로&amp;nbsp;오래&amp;nbsp;걸리지만&amp;nbsp;중요한&amp;nbsp;작업은&amp;nbsp;아침의&amp;nbsp;높은&amp;nbsp;에너지&amp;nbsp;시간대에&amp;nbsp;먼저&amp;nbsp;수행하는&amp;nbsp;것이&amp;nbsp;효과적입니다.&amp;nbsp;이른바&amp;nbsp;&amp;ldquo;개구리를&amp;nbsp;먼저&amp;nbsp;먹어라&amp;rdquo;라는&amp;nbsp;생산성&amp;nbsp;격언이&amp;nbsp;있는데,&amp;nbsp;가장&amp;nbsp;힘든&amp;nbsp;일을&amp;nbsp;미루지&amp;nbsp;말고&amp;nbsp;하루의&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;작업으로&amp;nbsp;처리하라는&amp;nbsp;뜻입니다.&amp;nbsp;필자도&amp;nbsp;심리적으로&amp;nbsp;부담되는&amp;nbsp;코딩&amp;nbsp;작업이나&amp;nbsp;까다로운&amp;nbsp;문제&amp;nbsp;해결을&amp;nbsp;오전&amp;nbsp;일찍&amp;nbsp;착수해&amp;nbsp;끝내놓으면,&amp;nbsp;그날&amp;nbsp;나머지&amp;nbsp;시간이&amp;nbsp;훨씬&amp;nbsp;가볍고&amp;nbsp;생산적으로&amp;nbsp;느껴졌습니다.&amp;nbsp;결국,&amp;nbsp;자기&amp;nbsp;시간을&amp;nbsp;지배한다는&amp;nbsp;것은&amp;nbsp;무엇에&amp;nbsp;시간을&amp;nbsp;투자하고&amp;nbsp;무엇을&amp;nbsp;과감히&amp;nbsp;버릴지&amp;nbsp;스스로&amp;nbsp;결정하는&amp;nbsp;일입니다.&amp;nbsp;업무상&amp;nbsp;불가피하게&amp;nbsp;해야&amp;nbsp;하는&amp;nbsp;일이라도&amp;nbsp;내가&amp;nbsp;주도권을&amp;nbsp;갖고&amp;nbsp;선택한&amp;nbsp;것처럼&amp;nbsp;인식하는&amp;nbsp;순간&amp;nbsp;몰입도와&amp;nbsp;만족도가&amp;nbsp;달라집니다.&amp;nbsp;시간&amp;nbsp;관리의&amp;nbsp;궁극적인&amp;nbsp;목표는&amp;nbsp;시간의&amp;nbsp;주인이&amp;nbsp;되어&amp;nbsp;삶과&amp;nbsp;업무&amp;nbsp;전반에서&amp;nbsp;더&amp;nbsp;큰&amp;nbsp;성취와&amp;nbsp;균형을&amp;nbsp;이루는&amp;nbsp;데&amp;nbsp;있다는&amp;nbsp;것을&amp;nbsp;기억해야&amp;nbsp;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;마무리, 우선순위를 지키는 습관이 경쟁력이다&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ktyn6/btsQdSkpkwl/iTlKLrkd9DfLoA0kIKKDAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ktyn6/btsQdSkpkwl/iTlKLrkd9DfLoA0kIKKDAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ktyn6/btsQdSkpkwl/iTlKLrkd9DfLoA0kIKKDAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKtyn6%2FbtsQdSkpkwl%2FiTlKLrkd9DfLoA0kIKKDAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;486&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;중요-긴급 매트릭스 활용&lt;/b&gt; : 오늘 해야 할 일을 네 가지 범주(중요&amp;middot;긴급 등)로 분류해 보세요. 긴급하지 않지만 중요한 일에 꾸준히 시간을 투자하는 계기가 됩니다. &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;시간 블록킹 시도 : 내일 일정표에 중요한 업무를 위한 집중 블록 시간을 미리 확보하세요. 그 시간만큼은 방해를 차단하고 몰입해 봅니다. &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;업무 중 한 가지에만 몰두&lt;/b&gt; : 작업할 때 방해가 되는 알림을 끄고 하나의 업무에만 집중하세요. 멀티태스킹을 줄이면 오히려 처리 속도가 빨라집니다. &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;2분 규칙 적용&lt;/b&gt; : 2분 이내에 끝낼 수 있는 이메일 답장이나 관리 업무가 있다면 바로바로 처리하여 작업 목록을 가볍게 유지하세요. &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;하루의 첫 임무로 어려운 일 수행&lt;/b&gt; : 미루기 쉬운 까다로운 작업을 아침 첫 작업으로 완료해 보세요(&amp;ldquo;개구리&amp;rdquo;부터 먹기). 남은 시간에 대한 자신감이 생깁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;소프트웨어&amp;nbsp;개발자를&amp;nbsp;비롯한&amp;nbsp;현대의&amp;nbsp;지식&amp;nbsp;노동자에게&amp;nbsp;시간&amp;nbsp;관리는&amp;nbsp;곧&amp;nbsp;자기&amp;nbsp;관리이며&amp;nbsp;경쟁력의&amp;nbsp;핵심입니다.&amp;nbsp;우리는&amp;nbsp;모두&amp;nbsp;같이&amp;nbsp;24시간을&amp;nbsp;받지만,&amp;nbsp;어떻게&amp;nbsp;사용하느냐에&amp;nbsp;따라&amp;nbsp;성과와&amp;nbsp;삶의&amp;nbsp;질은&amp;nbsp;극적으로&amp;nbsp;달라집니다.&amp;nbsp;급한&amp;nbsp;불을&amp;nbsp;끄느라&amp;nbsp;하루를&amp;nbsp;보낼&amp;nbsp;수도&amp;nbsp;있고,&amp;nbsp;장기적으로&amp;nbsp;가치&amp;nbsp;있는&amp;nbsp;일에&amp;nbsp;투자하여&amp;nbsp;미래를&amp;nbsp;준비할&amp;nbsp;수도&amp;nbsp;있습니다.&amp;nbsp;중요한&amp;nbsp;일에&amp;nbsp;우선순위를&amp;nbsp;두고,&amp;nbsp;하루를&amp;nbsp;계획적으로&amp;nbsp;설계하며,&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;한&amp;nbsp;가지&amp;nbsp;일에&amp;nbsp;집중하는&amp;nbsp;습관은&amp;nbsp;쉽게&amp;nbsp;길러지지&amp;nbsp;않지만,&amp;nbsp;꾸준히&amp;nbsp;실천하면&amp;nbsp;분명히&amp;nbsp;삶을&amp;nbsp;바꿔놓습니다.&amp;nbsp;이제&amp;nbsp;소개한&amp;nbsp;원칙들을&amp;nbsp;바탕으로&amp;nbsp;작은&amp;nbsp;변화부터&amp;nbsp;시작해 보세요.&amp;nbsp;여러분의&amp;nbsp;시간&amp;nbsp;사용&amp;nbsp;방식이&amp;nbsp;서서히&amp;nbsp;달라지고,&amp;nbsp;바쁜&amp;nbsp;일정&amp;nbsp;속에서도&amp;nbsp;정말&amp;nbsp;중요한&amp;nbsp;목표들을&amp;nbsp;차근차근&amp;nbsp;달성해 나가는&amp;nbsp;자신을&amp;nbsp;발견할&amp;nbsp;수&amp;nbsp;있을&amp;nbsp;것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DailyRoutine</category>
      <category>개발자</category>
      <category>생산성</category>
      <category>시간관리</category>
      <category>업무</category>
      <category>업무순위</category>
      <category>업무효율</category>
      <category>우선순위</category>
      <category>자기관리</category>
      <category>직장생활</category>
      <category>집중</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/548</guid>
      <comments>https://odinbox.tistory.com/548#entry548comment</comments>
      <pubDate>Sat, 30 Aug 2025 17:14:05 +0900</pubDate>
    </item>
    <item>
      <title>오라클 DBLINK 사용방법</title>
      <link>https://odinbox.tistory.com/547</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;DBLINK의 개념과 필요성 이해하기&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;font-weight: normal; position: relative; line-height: 40px; background: #007CBA; border: 1px solid #fff; padding: 10px; color: white; border-radius: 0 10px 0 10px; box-shadow: inset 0 0 5px rgba(53,86,129, 0.5); font-family: 'Muli', sans-serif; border-style: solid; border-width: 0px  0px  1px 15px; border-color: #232323; background-color: #007cba;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 15pt; color: #ffffff;&quot;&gt;&lt;b&gt;오라클 DBLINK에 대해서 알아봅시다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;글 상단 부분 대표 이미지 (7).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEDFxM/btsP5EZpnVM/1Ln9fC6uFV6NSOpJ3YOelk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEDFxM/btsP5EZpnVM/1Ln9fC6uFV6NSOpJ3YOelk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEDFxM/btsP5EZpnVM/1Ln9fC6uFV6NSOpJ3YOelk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEDFxM%2FbtsP5EZpnVM%2F1Ln9fC6uFV6NSOpJ3YOelk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;글 상단 부분 대표 이미지 (7).png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;실무에서 단일 오라클 데이터베이스만 사용하는 경우보다 여러 종류의 DBMS(ORACLE, MYSQL, POSTGRESQL 등)을 함께 사용하는 경우가 많습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;예를 들어, 현재 시스템에서 타 시스템과 연계하여 자료를 보여주어야 하는 경우가 흔히 많이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이때 DBLINK(Database Link)기능과 게이트웨이(Database Gateway, ODBC 연동)을 활용하면 서로 다른 DB간에도 데이터를 연계할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이번에는 오라클 DBLINK 개념과 설정 방법을 설명한 후 연결하는 방법등을 알아보려고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-style: solid; font-weight: bold; border-width: 1px  1px  1px 5px; border-color: #707070; background-color: #fff; padding: 10px;&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://tistory3.daumcdn.net/tistory/1569230/skin/images/jquery.toc.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	$(&quot;#toc&quot;).toc( {content: &quot;.tt_article_useless_p_margin&quot;, headings: &quot;h1,h2,h3,h4&quot; , top: -90, isBlink : true, blinkColor : '#21B9DE' } ) });
&lt;/script&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DBLINK&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DBLINK란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;오라클 DB에서 원격 DB(SQL 실행대상)에 접근할 수 있게 해주는 객체입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;용도의 경우 원격 DB 테이블 조회 및 조작, 분산 트랜잭션 처리, 이기종 DB 통합 등의 용도가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;오라클에서 오라클 DBLINK&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1755916205260&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;--생성 방법 1
CREATE DATABASE LINK remote_link
CONNECT TO remote_user IDENTIFIED BY password
USING 'tns_alias'; -- tnsnames.ora에 있는 이름과 맞춰야 함.

-- 생성 방법 2
CREATE DATABASE LINK remote_link
  CONNECT TO TEST
  IDENTIFIED BY &quot;비밀이다&quot;
  USING '(DESCRIPTION=
            (ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))
            (CONNECT_DATA=(SERVICE_NAME=TEST))
         )';

--확인 및 삭제
SELECT * FROM user_db_links;
DROP DATABASE LINK remote_link;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;PUBLIC DBLINK vs PRIVATE DBLINK&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Private DBLINK : 생성한 사용자만 사용가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Public DBLINK : 모든 사용자가 사용 가능 (보안 위협증가)&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;오라클에서 MYSQL DBLINK&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;오라클은 MYSQL과 직접 DBLINK라는 것을 지원하지 않습니다. 대신 Oracle Database Gateway for ODBC(DG4ODBC) 또는 hsodbc를 이용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. ODBC 드라이버 설치&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;MYSQL ODBC 드라이버(Connector/ODBC) 설치&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. odbc.ini 등록 (Linux)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916381700&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[mysql_dsn]
Driver=/usr/lib/libmyodbc5.so
Description=MySQL ODBC Driver
Server=127.0.0.1
Port=3306
Database=testdb
User=testuser
Password=testpwd&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. tnsnames.ora 등록&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916406743&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MYSQL_DBLINK =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))
    (CONNECT_DATA = (SID=dg4odbc))
    (HS=OK)
  )&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. DBLINK 생성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916421761&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE DATABASE LINK mysql_link
CONNECT TO &quot;testuser&quot; IDENTIFIED BY &quot;testpwd&quot;
USING 'MYSQL_DBLINK';&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 조회 &amp;amp; 삭제&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755917217519&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 조회
SELECT * FROM dba_db_links;
SELECT * FROM user_db_links;

-- 삭제
DROP DATABASE LINK remote_link;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. 사용예시&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916441327&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM customers@mysql_link;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;오라클에서 PostgreSQL 연결&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;PostgreSQL도 동일하게 DG4ODBC또는 Oracle Gateway for ODBC를 활용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. PostgreSQL ODBC 드라이버 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;psqlODBC 설치&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. odbc.ini 등록&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916584630&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[pg_dsn]
Driver=/usr/lib/psqlodbcw.so
Description=PostgreSQL ODBC
Servername=127.0.0.1
Port=5432
Database=pgdb
Username=pguser
Password=pgpwd&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. tnsnames.ora 등록&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916595710&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POSTGRES_DBLINK =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))
    (CONNECT_DATA = (SID=dg4odbc))
    (HS=OK)
  )&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. DBLINK 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916610139&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE DATABASE LINK pg_link
CONNECT TO &quot;pguser&quot; IDENTIFIED BY &quot;pgpwd&quot;
USING 'POSTGRES_DBLINK';&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 사용예시&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1755916622625&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM orders@pg_link;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실제 운영 환경 문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;성능저하&lt;/b&gt; : 이기종 DB는 변환 오버헤드가 크므로 대량 데이터 전송 시 ETL 권장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;문자셋 문자&lt;/b&gt; : MYSQL, POSTGRESQL에서 ORACLE 간 UTF-8에서 AL32UTF8 변환 오류 가능 -&amp;gt; HS_LANGUAGE 설정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;트랜잭션 문제&lt;/b&gt; : 분산 트랜잭션은 안전성이 떨어지므로 단일 조회 용도로만 DBLINK 권장&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DBLINK 사용 시 주의사항&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;성능 이슈&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- 네트워크 지연 발생 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- 대량 데이터 전송 시 성능 저하&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- JOIN 시 원격 DB에서 실행계획 차이 발생&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;보안 고려사항&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- PUBLIC DBLINK 사용 최소화&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- 비밀번호 암호화 문제 (12c 이후부터는 암호화 저장 지원)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- 권한 분리 원칙 적용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;대안 기술&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- ORACLE GOLDENGATE - 실시간 복제&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- ORACLE DATA GUARD - 고가용성 환경&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- ETL 도구 - 대용량 데이터 이동&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DBLINK 대안 기술&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;Oracle GoldenGate&lt;/b&gt; : 실시간 복제 (이기종 DB 지원)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;ETL 도구(Informatica, ODI 등)&lt;/b&gt; : 대용량 데이터 이동&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;Kafka + CDC&lt;/b&gt; : 실시간 데이터 스트리밍&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;DBLINK는 오라클간 연결뿐 아니라 MYSQL, POSTGRESQL 같은 이기종 DB 연결에도 활용 가능합니다. 하지만 이기종 DB 연결은 성능 저하, 문자셋, 트랜잭션 제약이 있으므로 소규모 조회, 연계 용도에 적합합니다. 운영환경에서는 DBLINK를 남용하기보다 데이터복제-ETL-CDC 같은 전문 솔루션과 함께 고려하는 것이 바람직합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEVELOPMENT</category>
      <category>DBLink</category>
      <category>DB연동</category>
      <category>MYSQL</category>
      <category>ODBC</category>
      <category>Oracle</category>
      <category>PostgreSQL</category>
      <category>분산트랜잭션</category>
      <category>성능최적화</category>
      <category>이기종DB</category>
      <category>인터페이스</category>
      <author>간지뽕빨리턴님</author>
      <guid isPermaLink="true">https://odinbox.tistory.com/547</guid>
      <comments>https://odinbox.tistory.com/547#entry547comment</comments>
      <pubDate>Sat, 23 Aug 2025 11:56:14 +0900</pubDate>
    </item>
  </channel>
</rss>