Search

HTTP X SpringBoot - RestTemplate & WebClient

HTTP X SpringBoot - RestTemplate & WebClient

HTTP μš”μ²­ λ©”μ‹œμ§€μ™€ μžλ°” μ›Ήκ°œλ°œ

β€’
HTTP λ©”μ‹œμ§€μ˜ 헀더 μ •λ³΄μ—λŠ” μš”μ²­ν•˜λŠ” λ¦¬μ†ŒμŠ€μ˜ νƒ€μž…, 길이, 인코딩 방식 λ“±μ˜ 정보가 포함될 수 μžˆμŠ΅λ‹ˆλ‹€.
β€’
Javaμ—μ„œλŠ” HttpURLConnection 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ„ 보낼 수 μžˆμŠ΅λ‹ˆλ‹€. μ˜ˆμ‹œ μ½”λ“œμ—μ„œλŠ” GET μš”μ²­μ„ λ³΄λ‚΄λŠ” 방법을 λ³΄μ—¬μ€λ‹ˆλ‹€.
β€’
λ˜ν•œ, Spring Bootμ—μ„œλŠ” RestTemplateκ³Ό WebClientλ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ„ 보낼 수 μžˆμŠ΅λ‹ˆλ‹€.

Java μ—μ„œ HTTP μš”μ²­ 보내기

: HttpURLConnection 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬, μš”μ²­μ„ 보내기

μ˜ˆμ‹œμ½”λ“œ

import java.net.HttpURLConnection; import java.net.URL; import java.io.BufferedReader; import java.io.InputStreamReader; public class HttpURLConnectionExample { public static void main(String[] args) { try { URL url = new URL("https://api.example.com/data"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); System.out.println("Response: " + response.toString()); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } } }
Java
볡사

Spring Boot μ—μ„œ HTTP μš”μ²­ 보내기

1. RestTemplate을 μ‚¬μš©ν•œ HTTP μš”μ²­

RestTemplate은 Springμ—μ„œ μ œκ³΅ν•˜λŠ” κ°„λ‹¨ν•œ HTTP 톡신을 μœ„ν•œ ν΄λž˜μŠ€μž…λ‹ˆλ‹€. λ‹€μ–‘ν•œ HTTP λ©”μ„œλ“œ(GET, POST, PUT, DELETE λ“±)λ₯Ό μ‚¬μš©ν•˜μ—¬ μš”μ²­μ„ 보낼 수 μžˆμŠ΅λ‹ˆλ‹€.
μ˜μ‘΄μ„±
maven
β€’
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
XML
볡사
gradle
β€’
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-web'
Plain Text
볡사

μ˜ˆμ‹œμ½”λ“œ

import org.springframework.web.client.RestTemplate; import org.springframework.http.ResponseEntity; // RestTemplate 객체 생성 RestTemplate restTemplate = new RestTemplate(); // GET μš”μ²­ 보내기 String url = "https://api.example.com/data"; ResponseEntity<String> response = restTemplate.getForEntity(url, String.class); // POST μš”μ²­ 보내기 String postUrl = "https://api.example.com/data"; String requestData = "{ \"key\": \"value\" }"; ResponseEntity<String> postResponse = restTemplate.postForEntity(postUrl, requestData, String.class);
Java
볡사

2. WebClient을 μ‚¬μš©ν•œ HTTP μš”μ²­

WebClientλŠ” 비동기적이고 λ¦¬μ•‘ν‹°λΈŒν•œ λ°©μ‹μœΌλ‘œ HTTP μš”μ²­μ„ 보낼 수 μžˆλŠ” λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€.
μ˜μ‘΄μ„±
maven
β€’
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
XML
볡사
gradle
β€’
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-webflux'
Plain Text
볡사

μ˜ˆμ‹œμ½”λ“œ

import org.springframework.web.reactive.function.client.WebClient; // WebClient 객체 생성 WebClient webClient = WebClient.create(); // GET μš”μ²­ 보내기 webClient.get() .uri("https://api.example.com/data") .retrieve() .bodyToMono(String.class) .subscribe(response -> { // μš”μ²­ ν›„ μ²˜λ¦¬ν•  λ‚΄μš© }); // POST μš”μ²­ 보내기 webClient.post() .uri("https://api.example.com/data") .bodyValue("{ \"key\": \"value\" }") .retrieve() .bodyToMono(String.class) .subscribe(response -> { // μš”μ²­ ν›„ μ²˜λ¦¬ν•  λ‚΄μš© });
Java
볡사

RestTemplate vs WebClient 비ꡐ

RestTemplate은 Spring μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 일반적으둜 μ‚¬μš©λ˜λŠ” 동기식 HTTP ν΄λΌμ΄μ–ΈνŠΈλ‘œ, HTTP μš”μ²­μ„ 보내고 응닡을 λ°›λŠ” κ°„λ‹¨ν•˜κ³  νŽΈλ¦¬ν•œ 방법을 μ œκ³΅ν•©λ‹ˆλ‹€.
λ°˜λ©΄μ— WebClientλŠ” Spring 5μ—μ„œ μ†Œκ°œλœ 비동기식, λ¦¬μ•‘ν‹°λΈŒ HTTP ν΄λΌμ΄μ–ΈνŠΈλ‘œ, λ¦¬μ•‘ν‹°λΈŒ ν”„λ‘œκ·Έλž˜λ° λͺ¨λΈκ³Ό ν•¨κ»˜ μž‘λ™ν•˜λ„λ‘ μ„€κ³„λ˜μ–΄ 있으며 RestTemplate에 λΉ„ν•΄ 더 λ‚˜μ€ μ„±λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.
RestTemplate은 μ—¬μ „νžˆ 널리 μ‚¬μš©λ˜κ³  μžˆμ§€λ§Œ, μƒˆλ‘œμš΄ ν”„λ‘œμ νŠΈμ—μ„œλŠ” ν˜„λŒ€μ μΈ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ¦¬μ•‘ν‹°λΈŒ 및 비동기적인 νŠΉμ„±κ³Ό λ”μš± μΌμΉ˜ν•˜λŠ” WebClientλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 ꢌμž₯λ©λ‹ˆλ‹€.
κ·ΈλŸ¬λ‚˜, RestTemplateκ³Ό WebClient λͺ¨λ‘ Spring Boot μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ HTTP μš”μ²­μ„ 보내고 응닡을 μ²˜λ¦¬ν•˜λŠ” 데 효과적으둜 μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€. 두 방법 쀑 선택은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ νŠΉμ • μš”κ΅¬μ‚¬ν•­κ³Ό λ””μžμΈμ— 따라 λ‹€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
RestTemplate은 Spring 5μ—μ„œλŠ” 주둜 WebClient둜 λŒ€μ²΄λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€. WebClientλŠ” λ¦¬μ•‘ν‹°λΈŒ(non-blocking) λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜μ—¬ μ„±λŠ₯상 이점을 κ°€μ§‘λ‹ˆλ‹€.
HTTP μš”μ²­ ν…ŒμŠ€νŠΈ μ‚¬μ΄νŠΈ

httpbin

HTTP μš”μ²­μ„ ν…ŒμŠ€νŠΈν•˜κ³  λ””λ²„κΉ…ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” 무료 온라인 μ„œλΉ„μŠ€μž…λ‹ˆλ‹€. 이 μ‚¬μ΄νŠΈλ₯Ό μ‚¬μš©ν•˜λ©΄ λ‹€μ–‘ν•œ μœ ν˜•μ˜ HTTP μš”μ²­μ„ 보낼 수 있으며, ν•΄λ‹Ή μš”μ²­μ— λŒ€ν•œ λ‹€μ–‘ν•œ μœ ν˜•μ˜ 응닡을 받을 수 μžˆμŠ΅λ‹ˆλ‹€.
1.
GET μš”μ²­ 확인
β€’
https://httpbin.org/get: κΈ°λ³Έ GET μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.
β€’
https://httpbin.org/anything: μ „μ†‘λœ λͺ¨λ“  것을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
2.
POST μš”μ²­ 확인
β€’
https://httpbin.org/post: μ „μ†‘λœ 데이터λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
3.
기타 μœ μš©ν•œ κΈ°λŠ₯
β€’
https://httpbin.org/status/{μƒνƒœ μ½”λ“œ}: μ§€μ •λœ HTTP μƒνƒœ μ½”λ“œλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
β€’
https://httpbin.org/headers: ν΄λΌμ΄μ–ΈνŠΈλ‘œλΆ€ν„° μ „μ†‘λœ 헀더λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
β€’
https://httpbin.org/cookies: ν΄λΌμ΄μ–ΈνŠΈλ‘œλΆ€ν„° μˆ˜μ‹ λœ μΏ ν‚€λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
β€’
https://httpbin.org/ip: ν΄λΌμ΄μ–ΈνŠΈμ˜ IP μ£Όμ†Œλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

RestTemplate, WebClient 을 μ΄μš©ν•œ HTTP μš”μ²­ μ‹€μŠ΅

β€’
ν”„λ‘œμ νŠΈ ꡬ쑰
β€’
ν”„λ‘œμ νŠΈ ν™˜κ²½
β€’
μž‘μ—… 파일
β€’
μ‹€ν–‰ κ²°κ³Ό

ν”„λ‘œμ νŠΈ ꡬ쑰

spring-http/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ main/ β”‚ β”‚ β”œβ”€β”€ java/ β”‚ β”‚ β”‚ └── com/ β”‚ β”‚ β”‚ └── joeun/ β”‚ β”‚ β”‚ └── springhttp/ β”‚ β”‚ β”‚ β”œβ”€β”€ dto/ β”‚ β”‚ β”‚ β”‚ └── HttpResponse.java β”‚ β”‚ β”‚ β”œβ”€β”€ ServletInitializer.java β”‚ β”‚ β”‚ └── SpringHttpApplication.java β”‚ β”œβ”€β”€ resources/ β”‚ β”‚ β”œβ”€β”€ application.properties β”‚ β”‚ β”œβ”€β”€ static/ β”‚ β”‚ └── templates/ └── build.gradle

ν”„λ‘œμ νŠΈ ν™˜κ²½

β€’
Spring boot version : 3.3.5
β€’
Group Id : com.aloha
β€’
Artifact Id : spring-http
β€’
Java version : JDK 17
β€’
Packaging : WAR
β€’
Dependency
β—¦
Spring Web
β—¦
Spring Reactive Web
β—¦
Spring Dev Tools
β—¦
Lombok

μž‘μ—… 파일

β€’
build.gradle
β€’
HttpResponse.java
β€’
SpringHttpApplication.java
β€’
build.gradle
dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.projectreactor:reactor-test' }
SQL
볡사
β€’
HttpResponse.java
package com.aloha.springhttp.dto; import java.util.Map; import lombok.Data; @Data public class HttpResponse { private Map<String, String> args; private Map<String, String> headers; private String origin; private String url; }
Java
볡사
β€’
SpringHttpApplication.java
package com.aloha.springhttp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.aloha.springhttp.dto.HttpResponse; @SpringBootApplication public class SpringHttpApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SpringHttpApplication.class, args); restTemplate(); restTemplateToObject(); webClient(); webClientToObject(); } /** * RestTemplate 을 μ‚¬μš©ν•œ HTTP μš”μ²­ */ public static void restTemplate() { System.out.println("########### RestTemplate ###########\n"); RestTemplate restTemplate = new RestTemplate(); // GET μš”μ²­ String getUrl = "https://httpbin.org/get"; String response = restTemplate.getForObject(getUrl, String.class); System.out.println("########### GET Response ########### \n" + response); // POST μš”μ²­ HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); String postUrl = "https://httpbin.org/post"; String requestData = "{key: value}"; HttpEntity<String> request = new HttpEntity<>(requestData, headers); String postResponse = restTemplate.postForObject(postUrl, request, String.class); System.out.println("########### POST Response ########### \n" + postResponse); } /** * RestTemplate μš”μ²­ -> 응닡 -> 객체둜 λ³€ν™˜ν•˜κΈ° * @throws JsonProcessingException */ public static void restTemplateToObject() throws JsonMappingException, JsonProcessingException { RestTemplate restTemplate = new RestTemplate(); ObjectMapper objectMapper = new ObjectMapper(); // GET μš”μ²­ String getUrl = "https://httpbin.org/get"; ResponseEntity<String> getResponseEntity = restTemplate.getForEntity(getUrl, String.class); String getResponseBody = getResponseEntity.getBody(); HttpResponse httpResponse = objectMapper.readValue(getResponseBody, HttpResponse.class); System.out.println("########### Response to Object (RestTemplate) ###########"); System.out.println(httpResponse); System.out.println(); } /** * WebClient λ₯Ό μ‚¬μš©ν•œ HTTP μš”μ²­ */ public static void webClient() { System.out.println("########### WebClient ###########\n"); WebClient webClient = WebClient.create(); // GET μš”μ²­ String getUrl = "https://httpbin.org/get"; String response = webClient.get() .uri(getUrl) .retrieve() .bodyToMono(String.class) .block(); // block()은 μš”μ²­ μ™„λ£Œλ₯Ό λŒ€κΈ°ν•˜κ³  κ²°κ³Όλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€. System.out.println("########### GET Response ########### \n" + response); // POST μš”μ²­ String postUrl = "https://httpbin.org/post"; String requestData = "{ key : value }"; String postResponse = webClient.post() // POST μš”μ²­ .uri(postUrl) // uri 지정 .contentType(MediaType.APPLICATION_JSON) // contentType μš”μ²­ 헀더 μ„€μ • .body(BodyInserters.fromValue(requestData)) // μš”μ²­ λ³Έλ¬Έ(body)을 μ„€μ • .retrieve() // μš”μ²­ .bodyToMono(String.class) // 슀트림 ν˜•νƒœλ‘œ 받은 응닡을 λͺ¨λ…Έλ‘œ λ³€ν™˜ .block(); // block()은 μš”μ²­ μ™„λ£Œλ₯Ό λŒ€κΈ°ν•˜κ³  κ²°κ³Ό λ°›μŒ System.out.println("########### POST Response ########### \n" + postResponse); } /** * WebClient μš”μ²­ -> 응닡 -> 객체둜 λ³€ν™˜ν•˜κΈ° * @throws JsonProcessingException */ private static void webClientToObject() throws JsonProcessingException { WebClient webClient = WebClient.create(); String getUrl = "https://httpbin.org/get"; HttpResponse httpResponse = webClient.get() .uri(getUrl) .retrieve() .bodyToMono(HttpResponse.class) .block(); // GetResponseλ₯Ό JSON λ¬Έμžμ—΄λ‘œ λ³€ν™˜ ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse = objectMapper.writeValueAsString(httpResponse); // JSON λ¬Έμžμ—΄μ„ User 객체둜 λ³€ν™˜ HttpResponse response = objectMapper.readValue(jsonResponse, HttpResponse.class); System.out.println("########### Response to Object (WebClient) ###########"); System.out.println(response.toString()); System.out.println(); } }
Java
볡사

μ‹€ν–‰ κ²°κ³Ό

########### RestTemplate ########### ########### GET Response ########### { "args": {}, "headers": { "Accept": "text/plain, application/json, application/*+json, */*", "Host": "httpbin.org", "User-Agent": "Java/1.8.0_202", "X-Amzn-Trace-Id": "Root=1-65409ad8-4108dc922304952c08309ec7" }, "origin": "14.37.8.141", "url": "https://httpbin.org/get" } ########### POST Response ########### { "args": {}, "data": "{key: value}", "files": {}, "form": {}, "headers": { "Accept": "text/plain, application/json, application/*+json, */*", "Content-Length": "12", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "Java/1.8.0_202", "X-Amzn-Trace-Id": "Root=1-65409ad8-19f9017679f786530b296b38" }, "json": null, "origin": "14.37.8.141", "url": "https://httpbin.org/post" } ########### Response to Object (RestTemplate) ########### HttpResponse(args={}, headers={Accept=text/plain, application/json, application/*+json, */*, Host=httpbin.org, User-Agent=Java/1.8.0_202, X-Amzn-Trace-Id=Root=1-65409ad9-09b29f6449dab4f70e43154a}, origin=14.37.8.141, url=https://httpbin.org/get) ########### WebClient ########### ########### GET Response ########### { "args": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip", "Host": "httpbin.org", "User-Agent": "ReactorNetty/1.0.38", "X-Amzn-Trace-Id": "Root=1-65409ada-1f78a58f3cd9db604c2ffe84" }, "origin": "14.37.8.141", "url": "https://httpbin.org/get" } ########### POST Response ########### { "args": {}, "data": "{ key : value }", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip", "Content-Length": "15", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "ReactorNetty/1.0.38", "X-Amzn-Trace-Id": "Root=1-65409ada-442b88ff2f1d5e7b21311f38" }, "json": null, "origin": "14.37.8.141", "url": "https://httpbin.org/post" } ########### Response to Object (WebClient) ########### HttpResponse(args={}, headers={Accept=*/*, Accept-Encoding=gzip, Host=httpbin.org, User-Agent=ReactorNetty/1.0.38, X-Amzn-Trace-Id=Root=1-65409adb-4efe9c325a44763652475ff6}, origin=14.37.8.141, url=https://httpbin.org/get)
Plain Text
볡사

동기&비동기, λΈ”λ‘œν‚Ή&λ…ΌλΈ”λ‘œν‚Ή

λΈ”λ‘œν‚Ή (Blocking)
λ…ΌλΈ”λ‘œν‚Ή (Non-Blocking)
동기식
μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ 기닀리며 λ‹€λ₯Έ μž‘μ—…μ„ ν•˜μ§€ μ•ŠμŒ
μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦¬μ§€λ§Œ λ‹€λ₯Έ μž‘μ—…μ„ ν•  수 있음
비동기식
μž‘μ—…μ„ μš”μ²­ν•œ ν›„ λ‹€λ₯Έ μž‘μ—…μ„ ν•˜μ§€ μ•ŠμŒ
μž‘μ—…μ„ μš”μ²­ν•œ ν›„ λ‹€λ₯Έ μž‘μ—…μ„ ν•  수 있음

λΉ„λ™κΈ°λž€?

μž‘μ—…μ„ μš”μ²­ν•œ ν›„ κ·Έ μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ 기닀리지 μ•Šκ³ , λ‹€λ₯Έ μž‘μ—…μ„ 계속할 수 μžˆλŠ” λ°©μ‹μž…λ‹ˆλ‹€. μž‘μ—…μ΄ μ™„λ£Œλ˜λ©΄ 콜백 ν•¨μˆ˜λ‚˜ 이벀트λ₯Ό 톡해 κ²°κ³Όλ₯Ό μ•Œλ €μ€λ‹ˆλ‹€.

λ…ΌλΈ”λ‘œν‚Ήμ΄λž€?

μž‘μ—…μ„ μš”μ²­ν•  λ•Œ, κ·Έ μž‘μ—…μ΄ μ¦‰μ‹œ μ™„λ£Œλ˜μ§€ μ•Šλ”λΌλ„ ν˜„μž¬ μž‘μ—…μ„ λ©ˆμΆ”μ§€ μ•Šκ³  λ‹€λ₯Έ μž‘μ—…μ„ 계속할 수 μžˆλŠ” λ°©μ‹μž…λ‹ˆλ‹€. 즉, μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ 기닀리지 μ•Šκ³  λ°”λ‘œ λ‹€μŒ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

동기식 λ…ΌλΈ”λ‘œν‚Ήμ΄ κ°€λŠ₯ν•œκ°€?

μΌλ°˜μ μœΌλ‘œλŠ” 동기식 λ…ΌλΈ”λ‘œν‚Ή 쑰합은 μ‹€λ¬΄μ—μ„œ 거의 μ‚¬μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 동기식 호좜이 λ…Όλ¦¬μ μœΌλ‘œ λΈ”λ‘œν‚Ήμ„ μˆ˜λ°˜ν•˜λŠ” νŠΉμ„±μ΄ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ΄λ‘ μ μœΌλ‘œλŠ” λ‹€μŒκ³Ό 같은 λ°©λ²•μœΌλ‘œ 동기식 λ…ΌλΈ”λ‘œν‚Ήμ„ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€
β€’
폴링(Polling): 일정 κ°„κ²©μœΌλ‘œ μž‘μ—… μƒνƒœλ₯Ό μ²΄ν¬ν•˜μ—¬ μ™„λ£Œλ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. μ΄λŠ” νŠΉμ • 주기둜 μž‘μ—… μ™„λ£Œ μ—¬λΆ€λ₯Ό ν™•μΈν•˜κ³ , μ™„λ£Œλ˜μ§€ μ•Šμ•˜λ‹€λ©΄ λ°”λ‘œ μ œμ–΄κΆŒμ„ λ°˜ν™˜ν•˜λŠ” λ°©μ‹μ΄λ―€λ‘œ λ…ΌλΈ”λ‘œν‚Ήμ²˜λŸΌ λ™μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
β€’
λ°”μœ λŒ€κΈ°(Busy-waiting): CPU μžμ›μ„ ν™œμš©ν•΄ λ¬΄ν•œ 루프λ₯Ό 돌며 κ²°κ³Όλ₯Ό κΈ°λ‹€λ¦¬λ˜, μž‘μ—…μ΄ μ™„λ£Œλ˜μ§€ μ•ŠμœΌλ©΄ λ‹€λ₯Έ 둜직으둜 μ œμ–΄λ₯Ό λ„˜κΈ°μ§€ μ•ŠλŠ” λ°©μ‹μž…λ‹ˆλ‹€.
ν•˜μ§€λ§Œ, μ΄λŸ¬ν•œ 방법은 CPU λ¦¬μ†ŒμŠ€λ₯Ό λ‚­λΉ„ν•  수 μžˆμœΌλ―€λ‘œ νš¨μœ¨μ μ΄μ§€ μ•ŠμœΌλ©°, 동기적 λ…ΌλΈ”λ‘œν‚Ήμ˜ ν•„μš”μ„±μ΄ 큰 κ²½μš°μ—λŠ” 비동기 λ…ΌλΈ”λ‘œν‚Ή 방식을 더 μ„ ν˜Έν•˜κ²Œ λ©λ‹ˆλ‹€.

Github (μ†ŒμŠ€μ½”λ“œ)