๐MSA์์์ HTTP ํด๋ผ์ด์ธํธ ์ฌ์ฉ
MSA ํ๊ฒฝ์์๋ ๊ฐ ์๋น์ค๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ๋์ํ๋ฉฐ, ์๋ก์ API๋ฅผ ํธ์ถํด์ผ ํ๋ค. ์ด๋ ๋ค์ํ HTTP ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์ฑ๋ฅ๊ณผ ์ ์ง๋ณด์๋ฅผ ๊ณ ๋ คํด ์ ์ ํ ๋ฐฉ์์ ์ ํํด์ผ ํ๋ค.
โ HTTP ํด๋ผ์ด์ธํธ๋ MSA์์๋ง ์ฌ์ฉํ ๊น?
โก๏ธ ์๋๋ค! ์ผ๋ฐ์ ์ธ ๋ชจ๋๋ฆฌ์ ์ํคํ
์ฒ์์๋ ๋ค๋ฅธ ์ธ๋ถ API ํธ์ถ์ ์ํด HTTP ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ๋ค.
โก๏ธ ํ์ง๋ง MSA์์๋ ์๋น์ค ๊ฐ ํต์ ์ด ํ์์ ์ด๋ฏ๋ก, OpenFeign ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํนํ ๋ง์ด ์ฌ์ฉ๋๋ค.
โ ์ผ๋ฐ์ ์ธ API ํธ์ถ๊ณผ์ ์ฐจ์ด์ ์?
โก๏ธ ๋ณดํต API ํธ์ถ์ ๋จ์ํ HTTP ์์ฒญ์ด์ง๋ง, MSA์์๋ ๋ ์ธ๋ฐํ HTTP ํด๋ผ์ด์ธํธ ์ค์ ์ด ํ์ํ๋ค.
- ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ(Eureka) ๋ฅผ ์ด์ฉํ ๋์ URL ๋งคํ
- ๋ก๋ ๋ฐธ๋ฐ์ฑ (Ribbon, Spring Cloud LoadBalancer)
- ๋ณด์ ๋ฐ ์ธ์ฆ ์ฒ๋ฆฌ (JWT, OAuth ๋ฑ)
๐ฅ HTTP ํด๋ผ์ด์ธํธ ๋น๊ต
๋ฐฉ์ | ๋๊ธฐ/๋น๋๊ธฐ | ์ฃผ์ ํน์ง | ์ฅ์ | ๋จ์ |
RestTemplate (Deprecated) | ๋๊ธฐ | Spring ๊ธฐ๋ณธ HTTP ํด๋ผ์ด์ธํธ (Spring 5 ์ดํ ๋น์ถ์ฒ) | ์ฌ์ฉ๋ฒ์ด ๊ฐ๋จ | Blocking ๋ฐฉ์, ์ ์ง๋ณด์ ์ด๋ ค์ |
WebClient | ๋น๋๊ธฐ | Spring WebFlux ๊ธฐ๋ฐ, Reactive ์ง์ | ์ฑ๋ฅ ์ฐ์, ํ์ฅ์ฑ ์ข์ | ์ฝ๋ ๋ณต์ก |
OkHttp / Apache HttpClient | ๋๊ธฐ/๋น๋๊ธฐ ๊ฐ๋ฅ | ์ ์์ค HTTP ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ์ธ๋ฐํ ์ ์ด ๊ฐ๋ฅ | ์ง์ ๊ตฌํ ํ์ |
OpenFeign | ๋๊ธฐ (๊ธฐ๋ณธ) | ์ ์ธํ API ํด๋ผ์ด์ธํธ, Spring Cloud ๊ณต์ ์ง์ | ์ฝ๋๊ฐ ๊ฐ๊ฒฐ, ์ ์ง๋ณด์ ์ฌ์ | ๊ธฐ๋ณธ์ ์ผ๋ก ๋๊ธฐ ์ฒ๋ฆฌ (๋น๋๊ธฐ๋ ์ค์ ํ์) |
๐ ์์ ์ฝ๋
โ 1. RestTemplate (Deprecated)
์ฃผ๋ฌธ ์๋น์ค → ์ํ ์๋น์ค API ํธ์ถ ์์
import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class ProductServiceClient { private final RestTemplate restTemplate = new RestTemplate(); public ProductDetailDTO getProductDetail(int productId) { String url = "http://product-service/api/query/products/" + productId; return restTemplate.getForObject(url, ProductDetailDTO.class); } } |
โ๏ธ ์ฅ์ : ๊ฐ๋จํ๊ฒ HTTP ์์ฒญ ๊ฐ๋ฅ
โ ๋จ์ : ๋๊ธฐ ๋ฐฉ์(Blocking)์ด๋ผ ์ฑ๋ฅ์ด ๋จ์ด์ง๊ณ , Spring 5๋ถํฐ ๋น์ถ์ฒ๋จ
โ 2. WebClient ์ฌ์ฉ (๋น๋๊ธฐ ๋ฐฉ์, ์ถ์ฒ!)
Spring WebFlux์ WebClient๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฐ๋ฅ!
import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @Service public class ProductServiceClient { private final WebClient webClient; public ProductServiceClient(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder.baseUrl("http://product-service").build(); } public ProductDetailDTO getProductDetail(int productId) { return webClient.get() .uri("/api/query/products/{id}", productId) .retrieve() .bodyToMono(ProductDetailDTO.class) .block(); // ๋๊ธฐ ์ฒ๋ฆฌ (๋น๋๊ธฐ๋ก ํ๋ ค๋ฉด .subscribe()) } } |
โ๏ธ ์ฅ์ : ๋น๋๊ธฐ(Non-blocking) ๋ฐฉ์, ์ฑ๋ฅ ์ฐ์, WebFlux์ ํจ๊ป ์ฌ์ฉํ๋ฉด ๋์ ํ์ฅ์ฑ ์ ๊ณต
โ ๋จ์ : ์ฝ๋๊ฐ ๋ค์ ๋ณต์ก
โ 3. OkHttp ๋๋ Apache HttpClient ์ง์ ์ฌ์ฉ
Low-Level HTTP Client๋ฅผ ์ง์ ๊ตฌํํ๋ ๋ฐฉ์
๋ณดํต OkHttp๋ Apache HttpClient ๊ฐ์ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ง์ ์จ์ผ ํจ.
์ด ๋ฐฉ์์ ๊ฑฐ์ ์ ์!
import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import com.fasterxml.jackson.databind.ObjectMapper; @Service public class ProductServiceClient { private final OkHttpClient client = new OkHttpClient(); private final ObjectMapper objectMapper = new ObjectMapper(); public ProductDetailDTO getProductDetail(int productId) throws Exception { Request request = new Request.Builder() .url("http://product-service/api/query/products/" + productId) .get() .build(); try (Response response = client.newCall(request).execute()) { return objectMapper.readValue(response.body().string(), ProductDetailDTO.class); } } } |
โ๏ธ ์ฅ์ : ์ธ๋ฐํ HTTP ์์ฒญ ์ ์ด ๊ฐ๋ฅ
โ ๋จ์ : ์ง์ ๊ตฌํํด์ผ ํ ๊ฒ์ด ๋ง์ (์ง์ ์์ฒญ ์์ฑ, ์๋ต ์ฒ๋ฆฌ)
โ 4. OpenFeign (์ถ์ฒ!)
@FeignClient(name = "์๋น์ค๋ช ")๋ง ํ๋ฉด Eureka๋ก ์๋น์ค ๊ฐ ํธ์ถ ๊ฐ๋ฅ!
@FeignClient(name = "product-service", url = "http://product-service") public interface ProductClient { @GetMapping("/api/query/products/{id}") ProductDetailDTO getProductDetail(@PathVariable("id") int id); } |
โ๏ธ ์ฅ์ : ์ ์ธํ ์ธํฐํ์ด์ค๋ง์ผ๋ก API ํธ์ถ ๊ฐ๋ฅ, ์ ์ง๋ณด์ ํธ๋ฆฌ, Spring Cloud์์ ๊ณต์ ์ง์
โ ๋จ์ : ๊ธฐ๋ณธ์ ์ผ๋ก ๋๊ธฐ ๋ฐฉ์ (๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ์ถ๊ฐ ์ค์ ํ์)
๐๊ฒฐ๋ก : ์ด๋ค ๋ฐฉ์์ ์ ํํ ๊น?
โก๏ธ ๋จ์ํ API ํธ์ถ: RestTemplate (ํ์ง๋ง ๋น์ถ์ฒ)
โก๏ธ ๋น๋๊ธฐ + ์ฑ๋ฅ ์ค์: WebClient
โก๏ธ ์ธ๋ฐํ HTTP ์ ์ด ํ์: OkHttp / Apache HttpClient
โก๏ธ MSA ํ๊ฒฝ์์ ๊ฐ์ฅ ํจ์จ์ : OpenFeign ( Spring Cloud ๊ณต์ ์ง์!)
OpenFeign์ ์ฐ๋ฉด ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ(Eureka)์ ์ฐ๊ณํ์ฌ ๋์ API ํธ์ถ์ด ๊ฐ๋ฅํ๋ฏ๋ก,
MSA ํ๊ฒฝ์์ ๊ฐ์ฅ ํจ์จ์ ์ด๋ค! ๐
'Backend > spring cloud (MSA)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Elasticsearch๋? (0) | 2025.04.10 |
---|---|
๋ฐ์ดํฐ ํตํฉ ์กฐํ ๋ฐฉ๋ฒ ์ค๊ณ (0) | 2025.04.06 |
MSA ํ๊ฒฝ์์ ์ธ์ฆ/ํ ํฐ ์ฌ์์ฒญ (0) | 2025.04.06 |
์ค์๊ฐ ๋ฐ์ดํฐ ์ ์ก (0) | 2025.02.23 |
[Kafka] ๊ณ ๊ธ ์ค์ (0) | 2025.02.23 |