<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>코딩묻은 디자이너</title>
    <link>https://w-world.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 13 Jul 2026 20:23:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>시즈코</managingEditor>
    <item>
      <title>[Elasticsearch] 삭제 작업 중 ES 모니터링 하기</title>
      <link>https://w-world.tistory.com/361</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img1.daumcdn.png&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lFVAF/btsK5mpzNwb/KvHj4jjRUfmiVNhBHJcWy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lFVAF/btsK5mpzNwb/KvHj4jjRUfmiVNhBHJcWy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lFVAF/btsK5mpzNwb/KvHj4jjRUfmiVNhBHJcWy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlFVAF%2FbtsK5mpzNwb%2FKvHj4jjRUfmiVNhBHJcWy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;225&quot; data-filename=&quot;img1.daumcdn.png&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Cluster 상태 모니터링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제 작업 중 Kibana의 Monitoring이나 /_cat/health API를 사용하여 클러스터 상태를 모니터링 할 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1733149382061&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GET /_cat/health?v=true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 코드&lt;/p&gt;
&lt;pre id=&quot;code_1733149362760&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X GET &quot;localhost:9200/_cat/health?v=true&amp;amp;pretty&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 예시&lt;/p&gt;
&lt;pre id=&quot;code_1733149465246&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cluster       status node.total node.data shards pri relo init unassign unassign.pri pending_tasks max_task_wait_time active_shards_percent
elasticsearch green           1         1      1   1    0    0        0            0             0                  -                100.0%&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;상태(status)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- grenn : 모든 샤드가 정상적으로 작동 중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- yellow : 일부 복제본 샤드가 활성화되지 않았지만, 데이터는 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- red : 일부 데이터 샤드가 손실된 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;노드 상태 모니터링&lt;/h2&gt;
&lt;pre id=&quot;code_1733149819096&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GET /_nodes/stats&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl코드&lt;/p&gt;
&lt;pre id=&quot;code_1733149849111&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X GET &quot;localhost:9200/_nodes/stats?pretty&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 예시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CPU 사용량&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Heap 메모리 사용량&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;pre id=&quot;code_1733149962112&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GET /_cat/shards?v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 코드&lt;/p&gt;
&lt;pre id=&quot;code_1733150000287&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X GET &quot;localhost:9200/_cat/shards?v=true&amp;amp;pretty&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력예시 :&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1733150012047&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;index       shard prirep state   docs  store ip            node
user_data   0     p      STARTED 10000 5mb   192.168.1.10 node-1
user_data   1     r      STARTED 10000 5mb   192.168.1.11 node-2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p : primary 샤드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r : replica 샤드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;state : STARTED, RELOCATING, INITIALIZING, UNASSIGNED 등의 사앹 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;작업 큐 상태 확인&lt;/h2&gt;
&lt;pre id=&quot;code_1733150181875&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GET /_cat/thread_pool?v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 코드&lt;/p&gt;
&lt;pre id=&quot;code_1733150237597&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;crul -X GET &quot;localhost:9200./_cat/shards?v=true&amp;amp;pretty&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 예시&lt;/p&gt;
&lt;pre id=&quot;code_1733150277315&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node_id   name    active queue rejected
node-1    write   2      15    0
node-2    search  0      10    5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;queue : 작업 대기열의 크기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rejected : 처리할 수 없어 거부된 작업 수(거부 작업이 많다면 리소스가 부족하다는 신호다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;_tasks를 통해 특정 작업 모니터링 하기(나의 경우 delete_by_query)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 코드&lt;/p&gt;
&lt;pre id=&quot;code_1733150537473&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X GET &quot;localhost:9200/_tasks?detailed=true&amp;amp;actions=*/delete/byquery&amp;amp;pretty&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력예시&lt;/p&gt;
&lt;pre id=&quot;code_1733150569709&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;nodes&quot;: {
    &quot;node-1&quot;: {
      &quot;tasks&quot;: {
        &quot;node-1:12345&quot;: {
          &quot;action&quot;: &quot;indices:data/write/delete/byquery&quot;,
          &quot;status&quot;: {
            &quot;total&quot;: 100000,
            &quot;deleted&quot;: 5000,
            &quot;version_conflicts&quot;: 0,
            &quot;throttled_millis&quot;: 0
          }
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굿굿&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ElasticSearch</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/361</guid>
      <comments>https://w-world.tistory.com/361#entry361comment</comments>
      <pubDate>Mon, 2 Dec 2024 23:43:36 +0900</pubDate>
    </item>
    <item>
      <title>[오류해결] waiting for chach lock: Could not get lock /var/lib/dpkg/lock-frontend.</title>
      <link>https://w-world.tistory.com/360</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dG6aiX/btsKVv1dJzB/peD6H831AJBB1FkuXYOX80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dG6aiX/btsKVv1dJzB/peD6H831AJBB1FkuXYOX80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dG6aiX/btsKVv1dJzB/peD6H831AJBB1FkuXYOX80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdG6aiX%2FbtsKVv1dJzB%2FpeD6H831AJBB1FkuXYOX80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;425&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend.에러&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 프로세스를 종료시킨다&lt;/p&gt;
&lt;pre id=&quot;code_1733056674668&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo killall apt apt-get&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 위 방법으로 효과가 없다면 디렉토리 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1733056722758&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock*&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 패키지 재구성&lt;/p&gt;
&lt;pre id=&quot;code_1733056749768&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo dpkg --configure -a&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 마무리&lt;/p&gt;
&lt;pre id=&quot;code_1733056765068&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 터미널이나, bash 창을 닫았다가 열어서 시도하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 체제 재부팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등으로 해결하였다는 분들도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1733056604604&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)&quot; data-og-description=&quot;I'm trying to run this command in the terminal: sudo apt install software-properties-common This is the error message I get: E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource&quot; data-og-host=&quot;askubuntu.com&quot; data-og-source-url=&quot;https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari&quot; data-og-url=&quot;https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cUojLi/hyXDmys6P1/RxcnfUP7ES3vTW9rffFDdK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cUojLi/hyXDmys6P1/RxcnfUP7ES3vTW9rffFDdK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I'm trying to run this command in the terminal: sudo apt install software-properties-common This is the error message I get: E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;askubuntu.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>study</category>
      <category>오류해결</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/360</guid>
      <comments>https://w-world.tistory.com/360#entry360comment</comments>
      <pubDate>Sun, 1 Dec 2024 21:40:54 +0900</pubDate>
    </item>
    <item>
      <title>[Elasticsearch] 데이터 삭제 중 락이 발생하지는 않을까?</title>
      <link>https://w-world.tistory.com/359</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img1.daumcdn.png&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uE8mi/btsKWTviQ6e/0x0fnIN81QQ4xEX860cWF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uE8mi/btsKWTviQ6e/0x0fnIN81QQ4xEX860cWF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uE8mi/btsKWTviQ6e/0x0fnIN81QQ4xEX860cWF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuE8mi%2FbtsKWTviQ6e%2F0x0fnIN81QQ4xEX860cWF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;225&quot; data-filename=&quot;img1.daumcdn.png&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엘라스틱 서치 작업을 해야하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDBMS만 다루다보니 삭제 작업에서 락이 발생하지는 않을지 궁금하여 찾아본 내용 정리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*RDBMS 는 MySQL 기준으로 작성&lt;/p&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;h3 data-ke-size=&quot;size23&quot;&gt;MySQL의 동작방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;REBMS에서 데이터 삭제가 조회/수정에 영향을 미치는 이유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 트랙잭션 관리 : MySQL은 ACID를 준수한다. 데이터를 삭제할 때, 해당 행을 잠그고 삭제가 완료되기 전까지 다른작업이 영향을 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 물리적 삭제 : MySQL은 데이터를 삭제할 때 디스크에서 데이터를 즉시 제거한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 락의 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행 레벨 락 : 삭제가 진행 중인 특정 행에 대해 검색/삽입 작업이 대기 상태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 락 : 대량 삭제가 테이블에 걸리는 락을 유발할 경우, 모든 작업이 영향을 받을 수 있다.&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;Elasticsearch의 동작방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL기반으로 분산형 아키텍처라 데이터 삭제 방식이 RDBMS와 다르다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;삭제 마킹&lt;/h4&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;/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;Elasticsearch 에서 검색과 삽입이 영향을 받지 않는 이유&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 읽기/쓰기 동시성 처리 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 샤드 기반 분산 처리를 사용하여 데이터가 여러 샤드에 분산되어 작업이 특정 샤드에서 이루어져도 다른 샤드에서는 검색 및 삽입 작업이 독립적으로 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 검색과 삭제 작업은 서로 다른 리소스를 사용하므로, 병렬 처리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 삭제가 논리적으로 처리됨 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 삭제는 문서 검색 결과에서 제외하는 논리적 작업에 불과하여 문서가 삭제되더라도 검색은 실시간으로 작동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. document 기반 데이터 모델 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터를 독립적인 문서 단위로 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 각 문서가 고유하여 삭제 작업이 진행 중이라도 다른 문서에 삽입되거나 검색될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 110px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;MySQL&lt;/td&gt;
&lt;td&gt;Elasticsearch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;삭제 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;물리적 삭제&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;논리적 삭제 (삭제 마킹)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;데이터 모델&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;행(row) 단위 관리&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;독립적인 문서(Document) 단위 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;트랜잭션 강제성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;ACID (강력한 일관성)&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;최종적 일관성 (Eventual Consistency)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;삭제 중 검색/삽입 영향&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;락 발생 가능성 높음&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;영향 거의 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;삭제 처리 시점&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;즉시 (삭제와 병합 동시 진행)&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;삭제는 나중에 병합 작업에서 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>study</category>
      <category>ElasticSearch</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/359</guid>
      <comments>https://w-world.tistory.com/359#entry359comment</comments>
      <pubDate>Wed, 27 Nov 2024 08:11:43 +0900</pubDate>
    </item>
    <item>
      <title>[Elasticsearch] 데이터 삭제</title>
      <link>https://w-world.tistory.com/358</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;download.png&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J8gUh/btsKVqsclwq/IjCt7WqCKWvazk78jODoOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J8gUh/btsKVqsclwq/IjCt7WqCKWvazk78jODoOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J8gUh/btsKVqsclwq/IjCt7WqCKWvazk78jODoOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ8gUh%2FbtsKVqsclwq%2FIjCt7WqCKWvazk78jODoOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;225&quot; data-filename=&quot;download.png&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Elasticsearch란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색 및 분석을 위한 분산형 오픈소스 데이터베이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 index라는 구조로 저장하고, 이를 통해 빠르고 유연한 검색이 가능&lt;/p&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;Document&lt;/b&gt; : Elasticsearch에서 데이터의 최소 단위(예 : JSON 형식의 데이터)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Index&lt;/b&gt; : Document들이 모여있는 데이터베이스와 유사한 개념&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Cluster/Node&lt;/b&gt; : 여러 개의 Index와 데이터를 저장하는 서버환경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Elasticsearch&amp;nbsp; 데이터 삭제 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 인덱스 전체 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1732459565744&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DELETE /index_name&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 조건에 맞는 Document 만 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1732459582683&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POST /index_name/_delete_by_query
{
  &quot;query&quot;: {
    &quot;match&quot;: {
      &quot;field_name&quot;: &quot;value&quot; // field_name, value 특정 조건
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Document ID 로 특정 데이터 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1732459655494&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DELETE /user_data/_doc/123&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엘라스틱서치 데이터 삭제시 주의해야할 사항으로는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터 복구가 불가능&lt;/b&gt;하기 때문에 삭제한 중요한 데이터는 삭제 전 백업이 꼭 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Elasticsearch 대량 삭제가 다른 작업에 미치는 영향&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;Elasticsearch는 분산형 아키텍처를 사용하기 때문에, 대량 삭제 작업이 진행되는 동안 검색 및 조회 가능하다&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;/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;_delete_by_query&amp;nbsp; 사용시 데이터를 검색하고 삭제하므로 CPU와 디스크 I/O를 많이 사용&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;h4 data-ke-size=&quot;size20&quot;&gt;. 사용자 활동이 적은시간(업무 외 시간, 야간)에 삭제 작업을 진행&lt;/h4&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;h4 data-ke-size=&quot;size20&quot;&gt;. Throttling 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: request_per_second 값을 설정하여 삭제 제한 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 초당 100건 삭제 제한&lt;/p&gt;
&lt;pre id=&quot;code_1732460045008&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POST /index_name/_delete_by_query?requests_per_second=100
{
  &quot;query&quot;: {
    &quot;match_all&quot;: {}
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;. Cluster 상태 모니터링&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kibana의 Monitoring 이나&lt;/p&gt;
&lt;pre id=&quot;code_1732460116817&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/_cat/health&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 사용해 클러스터 상태 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 상태가 green&amp;nbsp; 일 경우 클러스터가 안정적 상태라는 뜻&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;</description>
      <category>ElasticSearch</category>
      <category>엘라스틱서치</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/358</guid>
      <comments>https://w-world.tistory.com/358#entry358comment</comments>
      <pubDate>Sun, 24 Nov 2024 23:57:28 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 테이블 리스트 조회 방법_MySQL, Oracl</title>
      <link>https://w-world.tistory.com/357</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;DB 테이블 리스트 조회 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 업무를 하다보면 테이블 조회할 일이 많은데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERD가 문서화되어있지 않으면 일단 내가 어떤 테이블을 조회할 수 있는지 어떤 테이블이 있는지조차 몰라서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문의가 들어왔을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'엥...' 하고 있을 때가 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 새로운 시스템 업무를 조금씩 인수인계 받기 시작하면서 생소한 테이블도 조회를 하고 있는데 앞으로 내가 어떤 테이블을 다룰지 미리미리 확인을 하기 위해서 권한을 부여받은 DB의 테이블을 미리 확인해보려고 하였다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;MySQL&lt;/h3&gt;
&lt;pre id=&quot;code_1731247749573&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SHOW TABLES;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL에서는 show table로 현재 선택된 데이터베이스 내의 모든 테이블 출력 가능&lt;/p&gt;
&lt;pre id=&quot;code_1731247837163&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SHOW TABLES FROM 데이터베이스명;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 데이터베이스의 테이블을 조회하려면 데이터베이스 명을 입력한다&lt;/p&gt;
&lt;pre id=&quot;code_1731247866016&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT table_name 
FROM information_schema.tables
WHERE table_schema = '데이터베이스명' AND table_name LIKE '%키워드%';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 조건을 만족하는 테이블만 필터링 하기 위해서 infomation_schema.table 을 사용할 수있다&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;Oracle&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oracle에서는 ALL_TABLES 뷰를 통해 데이터베이스의 모든 테이블을 조회할 수 있지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 스키마별로 관리하고 있으므로 스키마에 따라결과가 달라질 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1731247957283&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT table_name 
FROM all_tables
WHERE owner = '스키마명';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 이름으로 필터링 가능&lt;/p&gt;
&lt;pre id=&quot;code_1731247978320&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT table_name
FROM all_tables
WHERE owner = '스키마명' AND table_name LIKE '%키워드%';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oracle에서는 ALL_TABLES, USER_TABLES, DBA_TABLES 세 가지 테이블 뷰가 있는데, 각 뷰는 다음과 같은 용도로 사용됩니다:&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;ALL_TABLES&lt;/b&gt;: 현재 사용자가 접근할 수 있는 모든 테이블&lt;/li&gt;
&lt;li&gt;&lt;b&gt;USER_TABLES&lt;/b&gt;: 현재 사용자에게 속한 테이블만 조회&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DBA_TABLES&lt;/b&gt;: 데이터베이스 내 모든 테이블 조회 (DBA 권한 필요)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DB</category>
      <category>MYSQL</category>
      <category>Oracle</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/357</guid>
      <comments>https://w-world.tistory.com/357#entry357comment</comments>
      <pubDate>Sun, 10 Nov 2024 23:15:40 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 히라가나 - 가타카나 단어 변경 라이브러리</title>
      <link>https://w-world.tistory.com/356</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pypi.org/project/jaconv/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pypi.org/project/jaconv/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1731163797670&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;jaconv&quot; data-og-description=&quot;Pure-Python Japanese character interconverter for Hiragana, Katakana, Hankaku, Zenkaku and more&quot; data-og-host=&quot;pypi.org&quot; data-og-source-url=&quot;https://pypi.org/project/jaconv/&quot; data-og-url=&quot;https://pypi.org/project/jaconv/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vDv9K/hyXs0CfZjR/hq0fZtUncWBkKzxSFUSitk/img.jpg?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300&quot;&gt;&lt;a href=&quot;https://pypi.org/project/jaconv/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pypi.org/project/jaconv/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vDv9K/hyXs0CfZjR/hq0fZtUncWBkKzxSFUSitk/img.jpg?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;jaconv&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pure-Python Japanese character interconverter for Hiragana, Katakana, Hankaku, Zenkaku and more&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pypi.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다운로드&lt;/h3&gt;
&lt;pre id=&quot;code_1731163838142&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install jaconv&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기능&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히라가나 -&amp;gt; 가타카나 전환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가타카나 -&amp;gt; 히라가나 전환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가능하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어 -&amp;gt; 히라가나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히라가나 -&amp;gt; 영어 기능도 제공한다고 위키에는 나와 있으나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실험해보니 해당 기능은 부족한 부분이 있는 것으로 보인다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731163973256&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import jaconv

# Hiragana to Katakana
jaconv.hira2kata('ともえまみ')
# =&amp;gt; 'トモエマミ'

# Hiragana to half-width Katakana
jaconv.hira2hkata('ともえまみ')
# =&amp;gt; 'ﾄﾓｴﾏﾐ'

# Katakana to Hiragana
jaconv.kata2hira('巴マミ')
# =&amp;gt; '巴まみ'

# half-width character to full-width character
# default parameters are followings: kana=True, ascii=False, digit=False
jaconv.h2z('ﾃｨﾛ･ﾌｨﾅｰﾚ')
# =&amp;gt; 'ティロ・フィナーレ'

# half-width character to full-width character
# but only ascii characters
jaconv.h2z('abc', kana=False, ascii=True, digit=False)
# =&amp;gt; 'ａｂｃ'

# half-width character to full-width character
# but only digit characters
jaconv.h2z('123', kana=False, ascii=False, digit=True)
# =&amp;gt; '１２３'

# half-width character to full-width character
# except half-width Katakana
jaconv.h2z('ｱabc123', kana=False, digit=True, ascii=True)
# =&amp;gt; 'ｱａｂｃ１２３'

# an alias of h2z
jaconv.hankaku2zenkaku('ﾃｨﾛ･ﾌｨﾅｰﾚabc123')
# =&amp;gt; 'ティロ・フィナーレabc123'

# full-width character to half-width character
# default parameters are followings: kana=True, ascii=False, digit=False
jaconv.z2h('ティロ・フィナーレ')
# =&amp;gt; 'ﾃｨﾛ・ﾌｨﾅｰﾚ'

# full-width character to half-width character
# but only ascii characters
jaconv.z2h('ａｂｃ', kana=False, ascii=True, digit=False)
# =&amp;gt; 'abc'

# full-width character to half-width character
# but only digit characters
jaconv.z2h('１２３', kana=False, ascii=False, digit=True)
# =&amp;gt; '123'

# full-width character to half-width character
# except full-width Katakana
jaconv.z2h('アａｂｃ１２３', kana=False, digit=True, ascii=True)
# =&amp;gt; 'アabc123'

# an alias of z2h
jaconv.zenkaku2hankaku('ティロ・フィナーレａｂｃ１２３')
# =&amp;gt; 'ﾃｨﾛ･ﾌｨﾅｰﾚａｂｃ１２３'

# normalize
jaconv.normalize('ティロ･フィナ〜レ', 'NFKC')
# =&amp;gt; 'ティロ・フィナーレ'

# Hiragana to alphabet
jaconv.kana2alphabet('じゃぱん')
# =&amp;gt; 'japan'

# Alphabet to Hiragana
jaconv.alphabet2kana('japan')
# =&amp;gt; 'じゃぱん'

# Katakana to Alphabet
jaconv.kata2alphabet('ケツイ')
# =&amp;gt; 'ketsui'

# Alphabet to Katakana
jaconv.alphabet2kata('namba')
# =&amp;gt; 'ナンバ'

# Hiragana to Julius's phoneme format
jaconv.hiragana2julius('てんきすごくいいいいいい')
# =&amp;gt; 't e N k i s u g o k u i:'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히라가나 - 가타카나 가타카나 - 히라가나 전환만 필요한 경우 해당 라이브러리를 이용하면 편리하다&lt;/p&gt;</description>
      <category>study/python</category>
      <category>python</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/356</guid>
      <comments>https://w-world.tistory.com/356#entry356comment</comments>
      <pubDate>Sat, 9 Nov 2024 23:54:26 +0900</pubDate>
    </item>
    <item>
      <title>[Python] pip 업그레이드 오류 해결하기</title>
      <link>https://w-world.tistory.com/355</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;python으로 pip 설치를 진행하다가 에러가 발생하였다&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;[notice]&amp;nbsp;A&amp;nbsp;new&amp;nbsp;release&amp;nbsp;of&amp;nbsp;pip&amp;nbsp;is&amp;nbsp;available:&amp;nbsp;24.2&amp;nbsp;-&amp;gt;&amp;nbsp;24.3.1 &lt;br /&gt;[notice]&amp;nbsp;To&amp;nbsp;update,&amp;nbsp;run:&amp;nbsp;python.exe&amp;nbsp;-m&amp;nbsp;pip&amp;nbsp;install&amp;nbsp;--upgrade&amp;nbsp;pip&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러의 원인은 버전이 낮아서 발생하는 것으로 pip upgrade가 필요하다&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;pre id=&quot;code_1730991637328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python.exe -m pip install --upgrade pip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬이 안내해주는 방식 그대로 사용하면 해결 가능하다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방법으로 pip를 업그레이드한 후 본래 사용하고 싶었던 명령어를 사용할 수 있었다.&lt;/p&gt;</description>
      <category>study/python</category>
      <category>python</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/355</guid>
      <comments>https://w-world.tistory.com/355#entry355comment</comments>
      <pubDate>Fri, 8 Nov 2024 00:02:55 +0900</pubDate>
    </item>
    <item>
      <title>[python] 가상 환경 활성화/비활성화 하기</title>
      <link>https://w-world.tistory.com/354</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Python&amp;nbsp; 가상환경 사용하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python에서는 가상 환경을 사용할 수 있고 특병 프로젝트에 맞춰서 패키지를 다르게 독립적으로 설정해줄 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전관리나 동일한 환경에서 다른사람들과 작업하기 편리하다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Python 가상환경 생성하기&lt;/h3&gt;
&lt;pre id=&quot;code_1730988159905&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;python -m venv '가상 환경 이름'&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Python 가상환경 활성화하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 가상 환경으로 이동 후 활성화&lt;/p&gt;
&lt;pre id=&quot;code_1730988260678&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd '가상 환경 이름 '
source Scripts/activate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령어를 입력하면 하단에('가상환경이름') 가상환경이 연결된걸 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 경우 venv로 대충 지음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bash에 입력시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sou + Tab S + Tab a + Tab&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tab 입력시 간편하게 자동완성 해준다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가상 환경에 패키지 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 환경에 접속 후 pip를 사용해서 패키지를 설치할 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1730988345365&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install requests&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 명령어를 입력하면 전역 환경에는 깔리지 않지만 나의 venv환경에서는 requests 라이브러리가 추가된다!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가상환경 비활성화&lt;/h3&gt;
&lt;pre id=&quot;code_1730989021098&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;deactivate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력하면 bash 하단의('가상환경이름') 이 사라진다&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;pre id=&quot;code_1730989087665&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rmdir&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가 팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 설치한 패키지와 버전을 한번에 txt 파일로 뽑아낼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1730989172840&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이대로 설치도 가능하다&lt;/p&gt;
&lt;pre id=&quot;code_1730989204493&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/pre&gt;</description>
      <category>study/python</category>
      <category>python</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/354</guid>
      <comments>https://w-world.tistory.com/354#entry354comment</comments>
      <pubDate>Thu, 7 Nov 2024 23:20:20 +0900</pubDate>
    </item>
    <item>
      <title>[React] 웹/모바일 감지하여 확인하여 화면 구분</title>
      <link>https://w-world.tistory.com/353</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 웹 사이트에 접속했을 때 웹으로 접속했는지, 모바일로 접속했는지에 따라 다른 화면을 보여주려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서는 현재 접속한 브라우저가 웹인지 모바일로 접속했는지에 대한 구분을 할 수 있어야 해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법을 찾아봤고 2가지 방법을 찾았다!&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;navigator.userAgent를 사용해 구분하는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;navigator.userAgent는 설치가 필요하지는 않다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724234471201&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const [browser, setBrowser] = useState()

.
.
.
// 초기 렌더링 후 한 번만 실행하기 위해 useEffect 사용
    useEffect(()=&amp;gt;{
        const user = navigator.userAgent;
        // 기본 환경 웹으로 설정
        setBrowser(&quot;web&quot;)
    	
        // userAgent 문자열에 iPhone, Android 일 경우 모바일로 업데이트
        if ( user.indexOf(&quot;iPhone&quot;) &amp;gt; -1 || user.indexOf(&quot;Android&quot;) &amp;gt; -1 ) {
            setBrowser(&quot;mobile&quot;)
        }
    },[])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;navigator.userAgent는 운영 체제 정보를 문자열로 반환해서 해당 문자열을 확인하여 웹과 모바일을 구분한다.&lt;/p&gt;
&lt;pre id=&quot;code_1724234659599&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;return ( 
        browser === &quot;web&quot; ? 
        &amp;lt;&amp;gt;
            &amp;lt;div&amp;gt;
			...
            &amp;lt;/div&amp;gt;
        &amp;lt;/&amp;gt; :
        &amp;lt;&amp;gt;
        	&amp;lt;div&amp;gt;
			...
           	&amp;lt;/div&amp;gt;
        &amp;lt;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 === &quot;변수1&quot; ? &amp;lt;&amp;gt;&amp;lt;/&amp;gt; : &amp;lt;&amp;gt;&amp;lt;/&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 형식으로 다른 div를 노출하도록 만들었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째 방법으로 찾은거&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;react-device-detect를 설치하여 환경 구분&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/package/react-device-detect&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.npmjs.com/package/react-device-detect&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724234838308&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;react-device-detect&quot; data-og-description=&quot;Detect device type and render your component according to it. Latest version: 2.2.3, last published: 2 years ago. Start using react-device-detect in your project by running &amp;#96;npm i react-device-detect&amp;#96;. There are 1195 other projects in the npm registry usin&quot; data-og-host=&quot;www.npmjs.com&quot; data-og-source-url=&quot;https://www.npmjs.com/package/react-device-detect&quot; data-og-url=&quot;https://www.npmjs.com/package/react-device-detect&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/byCHfu/hyWShcj9kc/Mg0VFKfugGT56Kk7LAC2S0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/package/react-device-detect&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.npmjs.com/package/react-device-detect&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/byCHfu/hyWShcj9kc/Mg0VFKfugGT56Kk7LAC2S0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;react-device-detect&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Detect device type and render your component according to it. Latest version: 2.2.3, last published: 2 years ago. Start using react-device-detect in your project by running `npm i react-device-detect`. There are 1195 other projects in the npm registry usin&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.npmjs.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. react-device-detect를 설치한다&lt;/p&gt;
&lt;pre id=&quot;code_1724234859391&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install --save react-device-detect&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 사용할 페이지에서 react-device-detect를 import하여 사용&lt;/p&gt;
&lt;pre id=&quot;code_1724234993847&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;import React, { useState } from 'react';

import { BrowserView, MobileView } from 'react-device-detect';


function Main() {
    return ( 
        &amp;lt;div className='container'&amp;gt;
            &amp;lt;BrowserView&amp;gt;
                &amp;lt;Content
                &amp;lt;/Content&amp;gt;
            &amp;lt;/BrowserView&amp;gt;
            &amp;lt;MobileView&amp;gt;
                &amp;lt;ContentMobile
                &amp;lt;/ContentMobile&amp;gt;
            &amp;lt;/MobileView&amp;gt;
        &amp;lt;/div&amp;gt;
     );
}

export default Main;​&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹뷰와 모바일뷰의 컴포넌트를 따로 생성하여 불러오도록 만들었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 작성하면 웹에서 접속시 Content를 모바일에서 접속시 ContentMobile을 불러와서 화면에 띄워준다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 화면 뿐만 아니라 import 해오는 패키지가 다른 경우에 이걸 사용해서 페이지를 분리했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/353</guid>
      <comments>https://w-world.tistory.com/353#entry353comment</comments>
      <pubDate>Wed, 21 Aug 2024 19:16:20 +0900</pubDate>
    </item>
    <item>
      <title>사이트에 메일 시스템 만들기-EmailJS react로 구성하기</title>
      <link>https://w-world.tistory.com/352</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현재 개인 프로젝트를 하면서 백엔드 서버 구성 없이 프론트엔드만으로 사이트를 구성중이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이트 사용자들이 나에게 의견이나 후기? 등을 작성해서 보내줄 수 있도록 이메일 보내기(Contact Us)를 만들려고&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;EmailJS&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;/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;이런저런 이유로 EmailJS를 사용하기로 했다!&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;EmailJS 사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.emailjs.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.emailjs.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722955339069&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Send email directly from your code | EmailJS&quot; data-og-description=&quot;No server side code required. Add static or dynamic attachments, dynamic parameters, captcha code and more. Start with our free tier!&quot; data-og-host=&quot;www.emailjs.com&quot; data-og-source-url=&quot;https://www.emailjs.com/&quot; data-og-url=&quot;https://www.emailjs.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/baLHV1/hyWKEySfQP/JsfodqQrnRMrMisomAHOpk/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200&quot;&gt;&lt;a href=&quot;https://www.emailjs.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.emailjs.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/baLHV1/hyWKEySfQP/JsfodqQrnRMrMisomAHOpk/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Send email directly from your code | EmailJS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;No server side code required. Add static or dynamic attachments, dynamic parameters, captcha code and more. Start with our free tier!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.emailjs.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 페이지 접속&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1897&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cv8R7U/btsIVEG0xcS/nN82x5J0r1omFnSL8oeCZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cv8R7U/btsIVEG0xcS/nN82x5J0r1omFnSL8oeCZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cv8R7U/btsIVEG0xcS/nN82x5J0r1omFnSL8oeCZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcv8R7U%2FbtsIVEG0xcS%2FnN82x5J0r1omFnSL8oeCZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1897&quot; height=&quot;942&quot; data-origin-width=&quot;1897&quot; data-origin-height=&quot;942&quot;/&gt;&lt;/span&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/bgU0PZ/btsIVFslI4u/lS3Ae2Mvm0cnknyrOUSPsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgU0PZ/btsIVFslI4u/lS3Ae2Mvm0cnknyrOUSPsk/img.png&quot; data-origin-width=&quot;1917&quot; data-origin-height=&quot;938&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4573%; margin-right: 10px;&quot; data-widthpercent=&quot;50.04&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgU0PZ/btsIVFslI4u/lS3Ae2Mvm0cnknyrOUSPsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgU0PZ%2FbtsIVFslI4u%2FlS3Ae2Mvm0cnknyrOUSPsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1917&quot; height=&quot;938&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Myzkl/btsIWviivZr/KxJCQ2L4xJVoWJlOsd2xW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Myzkl/btsIWviivZr/KxJCQ2L4xJVoWJlOsd2xW1/img.png&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;938&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.3799%;&quot; data-widthpercent=&quot;49.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Myzkl/btsIWviivZr/KxJCQ2L4xJVoWJlOsd2xW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMyzkl%2FbtsIWviivZr%2FKxJCQ2L4xJVoWJlOsd2xW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1914&quot; height=&quot;938&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EmailJS를 사용하기 위해서는 위 페이지에 들어가서 가입을 해야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wGkqn/btsIWD1xqS8/IU0WeTs4gwy2l3ynmw7TXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wGkqn/btsIWD1xqS8/IU0WeTs4gwy2l3ynmw7TXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wGkqn/btsIWD1xqS8/IU0WeTs4gwy2l3ynmw7TXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwGkqn%2FbtsIWD1xqS8%2FIU0WeTs4gwy2l3ynmw7TXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1918&quot; height=&quot;942&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;942&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가입하면 이 화면처럼 나오는데 Add New Service를 눌러서 서비스를 추가한다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/st24P/btsIXch5Dhd/KlsSRwW4KHSk6K6K1kaKj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/st24P/btsIXch5Dhd/KlsSRwW4KHSk6K6K1kaKj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/st24P/btsIXch5Dhd/KlsSRwW4KHSk6K6K1kaKj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fst24P%2FbtsIXch5Dhd%2FKlsSRwW4KHSk6K6K1kaKj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1916&quot; height=&quot;942&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;942&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;617&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzRSHn/btsI0uxlBvT/OmRAYcuESKzposT4iltmrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzRSHn/btsI0uxlBvT/OmRAYcuESKzposT4iltmrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzRSHn/btsI0uxlBvT/OmRAYcuESKzposT4iltmrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzRSHn%2FbtsI0uxlBvT%2FOmRAYcuESKzposT4iltmrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;617&quot; height=&quot;594&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이메일을 연결한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;943&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXpBky/btsI1dnNSH5/I0NyDnZ9YPGfWWvYkfKt40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXpBky/btsI1dnNSH5/I0NyDnZ9YPGfWWvYkfKt40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXpBky/btsI1dnNSH5/I0NyDnZ9YPGfWWvYkfKt40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXpBky%2FbtsI1dnNSH5%2FI0NyDnZ9YPGfWWvYkfKt40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1914&quot; height=&quot;943&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;943&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;783&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgUmC3/btsI0095SNk/3Z29k7EblDW1mmq7614QiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgUmC3/btsI0095SNk/3Z29k7EblDW1mmq7614QiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgUmC3/btsI0095SNk/3Z29k7EblDW1mmq7614QiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgUmC3%2FbtsI0095SNk%2F3Z29k7EblDW1mmq7614QiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1908&quot; height=&quot;783&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;783&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 테스트로 이렇게 커스텀해봤다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 Test It 버튼을 누르면 TEST도 가능한데, TEST도 하루 메일 보낼 수 있는 양을 차감한다&lt;/p&gt;
&lt;pre id=&quot;code_1723223642279&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;...

const [formData, setFormData] = useState({
    name : 'name',
    message : 'sample'
})    


...

const sendEmail = (e) =&amp;gt;{

    emailjs.send(&quot;service_ID&quot;,&quot;template_ID&quot;,formData,'PUBLICC_KEY')
    .then((response) =&amp;gt; {
        console.log(&quot;success&quot;,response.status, response.text)
        setFormData()
    },(error) =&amp;gt; {
        console.log('FAILED',error)
    })
}

...

&amp;lt;form&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;input type=&quot;text&quot; placeholder=&quot;이름&quot; name=&quot;name&quot; onChange={handleChange}&amp;gt;&amp;lt;/input&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;input type=&quot;textarea&quot; placeholder=&quot;내용&quot; name=&quot;message&quot; onChange={handleChange}&amp;gt;&amp;lt;/input&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;button type=&quot;submit&quot; onClick={sendEmail}&amp;gt;보내기&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 보내기 위해서는 위에서 커스텀 한&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;{{ name }}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;{{ message }}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 포함한 form을 만들어주고 입력한 값이 보내지도록 한다&lt;/p&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;SERVICE ID&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TEMPLATE ID&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PUBLIC KEY&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 필요한데 각각 아래 이미지 부분에서 확인할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SERVICE ID&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1909&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ETlFz/btsI1eAeQlL/fsuPPsCslgDKgOV5yUOXFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ETlFz/btsI1eAeQlL/fsuPPsCslgDKgOV5yUOXFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ETlFz/btsI1eAeQlL/fsuPPsCslgDKgOV5yUOXFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FETlFz%2FbtsI1eAeQlL%2FfsuPPsCslgDKgOV5yUOXFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1909&quot; height=&quot;940&quot; data-origin-width=&quot;1909&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;TEMPLATE ID&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1906&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXLH7q/btsIZxBBKmE/9KD8Ic2OuWkTHMDG737UZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXLH7q/btsIZxBBKmE/9KD8Ic2OuWkTHMDG737UZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXLH7q/btsIZxBBKmE/9KD8Ic2OuWkTHMDG737UZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXLH7q%2FbtsIZxBBKmE%2F9KD8Ic2OuWkTHMDG737UZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1906&quot; height=&quot;866&quot; data-origin-width=&quot;1906&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PUBLIC KEY&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;751&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRvjvu/btsI0g0o6Pm/rK2pZDNszGhs3QgIGOD6Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRvjvu/btsI0g0o6Pm/rK2pZDNszGhs3QgIGOD6Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRvjvu/btsI0g0o6Pm/rK2pZDNszGhs3QgIGOD6Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRvjvu%2FbtsI0g0o6Pm%2FrK2pZDNszGhs3QgIGOD6Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1894&quot; height=&quot;751&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;751&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 필요한 ID, KEY를 입력하고 sendEmail을 하면 메일이 내가 설정한 폼의 형태로 온다!&lt;/p&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;200 개&lt;/b&gt;의 메시지를 수신받을 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;남은 메일 수는 Account &amp;gt; Subscription Remaining quota 에서 확인 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이트 이요자가 나에게 메일을 보낼 수 있는 시스템으로 이용도 가능하지만 특정 행동에 코드를 심어두면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 특정 페이지를 방문하거나 클릭 혹은 이동 했을 때 나에게 메일이 올 수 있도록 설정하는 것도 가능할 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 일단 지금 프로젝트에서는 사용자들이 나에게 메일을 보낼 수 있도록 하는 용도로만 사용할 것 같다.&lt;/p&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;</description>
      <category>React</category>
      <author>시즈코</author>
      <guid isPermaLink="true">https://w-world.tistory.com/352</guid>
      <comments>https://w-world.tistory.com/352#entry352comment</comments>
      <pubDate>Sat, 10 Aug 2024 22:36:38 +0900</pubDate>
    </item>
  </channel>
</rss>