SPRING
2018.03.23 / 01:50

Spring WebFlux ±â¹Ý ¼­¹ö¸®½º ¾ÖÇø®ÄÉÀÌ¼Ç ¸¸µé¾îº¸±â

º½ÀÌ
Ãßõ ¼ö 322

Spring WebFlux ±â¹Ý ¼­¹ö¸®½º ¾ÖÇø®ÄÉÀÌ¼Ç ¸¸µé¾îº¸±â

¸î ÇØ ÀüºÎÅÍ ¼­¹ö¸®½º(Serverless)¶ó´Â ´Ü¾î¸¦ ºÃÁö¸¸, ÀÏÇϴ ȯ°æ°ú´Â °Å¸®°¡ ÀÖ´Â ´Ü¾î¶ó ±í°Ô °ü½ÉÀ» °¡Áö°í ã¾Æº» ÀûÀº ¾ø¾ú´Ù. ÀÛ³âºÎÅÍ AWS ±â¹Ý¿¡¼­ ½Ã½ºÅÛÀ» ±¸ÃàÇÏ°í, ¿î¿µÇÏ´Â ÀÏÀ» ÇÏ°Ô µÇ¸é¼­ Ŭ¶ó¿ìµå ³×ÀÌƼºê(Cloud Native)¿Í ¼­¹ö¸®½º¿¡ ´ëÇØ °ü½ÉÀ» °¡Áö°í Àû±ØÀûÀ¸·Î ÇнÀµµ ÇÏ°í, ½Ã½ºÅÛ¿¡ Àû¿ëµµ Çغ¸´Â ÁßÀÌ´Ù.

¼­¹ö¸®½º¶ó´Â ¿ë¾î´Â ´Ù¾çÇÑ Àǹ̷Π¾²ÀÌ°í ÀÖ´Â °ÍÀ¸·Î º¸À̸ç, ¸¶Æ¾ ÆÄ¿ï·¯ ¾ÆÀú¾¾°¡ Á¤¸®ÇÏ°í Àִ ¼­¹ö¸®½º ¾ÆÅ°ÅØó(Serverless Architectures) ±ÛÀ» ÅëÇØ ¾î´À Á¤µµ °¨À» ÀâÀ» ¼ö ÀÖ´Ù.

¸îÀÏÀü .NET Core 2.0 ¹ßÇ¥ ¼Ò½ÄÀ» µè°í, °ü·Ã ÀÚ·áµéÀ» µÚÀû°Å¸®´Ù 'Creating a Serverless Application with ASP.NET Core, AWS Lambda and AWS API Gateway' ±Û¿¡¼­ ²Ï Èï¹Ì·Î¿î ±×¸²À» ºÃ´Ù.

Serverless Application with ASP.NET Core

ÀüÅëÀûÀ¸·Î ASP.NET ¾ÖÇø®ÄÉÀ̼ÇÀº IIS/Nginx -> Kestrel(A cross platform web server for ASP.NET Core) -> ASP.NET Core Hosting ÇüÅ¿¡ ±¸Á¶¸¦ ¶ì³ª, ¼­¹ö¸®½º ±â¹Ý¿¡¼­ ¾ÖÇø®ÄÉÀ̼ÇÀ» °³¹ßÇÒ ¶§´Â IIS/Nginx¿¡ ¿ªÇÒÀ» AWS API Gateway°¡ ¼öÇàÇÏ°í, Kestrel¿¡ ¿ªÇÒÀ» AWS Lambda°¡ ¼öÇàÇÏ´Â ÇüÅ·Π±¸Á¶¸¦ ¸¸µç´Ù´Â °ÍÀÌ´Ù. ¿ªÇÒÀ» ¼öÇàÇÏ´Â µµ±¸µéÀÌ º¯°æµÇ¾úÀ½¿¡µµ °³¹ßÀÚ°¡ ÀÛ¼ºÇÏ´Â ÄÚµå´Â ÀüÅëÀûÀÎ ASP.NET ¾ÖÇø®ÄÉÀ̼ÇÀ» °³¹ßÇÏ´Â ¹æ¹ý Å©°Ô ´Ù¸£Áö ¾Ê¾Æ º¸ÀδÙ. ASP.NET Core HostingÀÌ ÁÖ¾îÁø »óȲ¿¡ µû¶ó ÀûÀýÇÏ°Ô ´ëÀÀÇÒ ¼ö ÀÖ´Â À¯¿¬ÇÔÀ» °®Ãß¾ú±â ¶§¹®¿¡ ÀÌ·± ±¸Á¶¿¡ ¾ÖÇø®ÄÉÀ̼ÇÀ» °³¹ßÇÏ´Â °ÍÀÌ °¡´ÉÇØ º¸¿´´Ù.

²Ï.. ¾Æ´Ï »ó´çÈ÷ ¸Å·ÂÀûÀÎ ±¸Á¶´Ù. ÇÊ¿ä¿¡ µû¶ó ±â¹Ý µµ±¸µéÀº ¾ðÁ¦µçÁö º¯°æÇÒ ¼ö ÀÖ°í, ¼­¹ö¸®½º°¡ ÁÖ´Â ÀÌÁ¡µéÀ» ÃæºÐÈ÷ ´©¸± ¼öµµ Àֱ⠶§¹®ÀÌ´Ù.

ÀÚ¹Ù¿Í ½ºÇÁ¸µÀ¸·Î À§¿Í °°Àº ±¸Á¶¸¦ ¸¸µé ¼ö ÀÖÀ»±î?

´çÀå ¸Ó¸´¼Ó¿¡¼­ ¶°¿À¸¥ ±¸Á¶´Â ¾Æ·¡¿Í °°´Ù.

Lambda°¡ ¼­ºí¸´ ÄÁÅ×À̳Ê(Servlet container) °¡¸éÀ» ¾²°í, API Gateway·ÎºÎÅÍ ÀÔ·ÂµÈ ¸Þ½ÃÁö·Î HttpServletReqeust¿Í HttpServletResponse¸¦ ¸¸µç ÈÄ Spring Web MVC¿¡ Àü´ÞÇϸé, ¿äû 󸮺ÎÅÍ ÀÀ´ä ÀÛ¼º±îÁö ¼öÇàÇÏ´Â ÇüÅ´Ù. Ȥ½Ã³ª ÇÏ°í ã¾Æº¸´Ï ¿ª½Ã ºñ½ÁÇÑ »ý°¢À» °¡Áö°í ±¸ÇöµÈ ¿ÀǼҽº aws-serverless-java-container°¡ ÀÖ´Ù.

aws-serverless-java-container

aws-serverless-java-container´Â Amazon Web Services - Labs¿¡¼­ ÁÖµµÀûÀ¸·Î °³¹ßÇϸç, À̲ô´Â ÇÁ·ÎÁ§Æ®·Î º¸ÀδÙ. AWS Lambda¿¡¼­ SpringJerseySpark ±â¹Ý ¾ÖÇø®ÄÉÀ̼ÇÀ» ÀÛ¼ºÇÒ ¼ö ÀÖµµ·Ï Áö¿øÇØÁØ´Ù. À̽´ ¸ñ·ÏÀ» »ìÆ캸´Ï Apache CamelPlay Framework µî ´Ù¾çÇÑ ÇÁ·¹ÀÓ¿öÅ©µéÀ» Áö¿øÇϱâ À§ÇØ ÁغñÇÏ°í ÀÖ´Â °ÍÀ¸·Î º¸ÀδÙ.

À§¿Í °°Àº ±¸Á¶°¡ Áö±ÝÀ¸·Î¼± ÃÖ¼±Àϱî?

ÀÚ¹Ù·Î À¥ ±â¹Ý ¾ÖÇø®ÄÉÀ̼ÇÀ» °³¹ßÇϱâ À§Çؼ­´Â ¼­ºí¸´(Servlet)°ú ¼­ºí¸´ ÄÁÅ×À̳Ê(Servlet container)¸¦ »ç¿ëÇÑ´Ù. ¹°·Ð ³×Æ®¿öÅ© ¹× ½º·¹µå Á¦¾î, ¿äû°ú ÀÀ´ä ó¸® µî ¹Ù´ÚºÎÅÍ ½×¾Æ¿Ã¸®¸é ¼­ºí¸´°ú ¼­ºí¸´ ÄÁÅ×À̳ʸ¦ »ç¿ëÇÏÁö ¾Ê°íµµ ¸ø¸¸µé ÀÌÀ¯´Â ¾øÁö¸¸ À¯Áöº¸¼ö¼ºÀ̳ª »ý»ê¼º µîÀ» »ý°¢Çغ¸¸é ºñÈ¿À²ÀûÀÌ´Ù. ±×·¡¼­ ÀÚ¹Ù »ýÅ°迡 À¥ ÇÁ·¹ÀÓ¿öÅ©(Web Framework)´Â ´ëºÎºÐ ¼­ºí¸´ À§¿¡ Ãß»óÈ­ °èÃþÀ» ¿Ã¸®´Â ÇüÅ·Π¸¸µé¾îÁ® ÀÖ´Ù. (Play Framework´Â ¼­ºí¸´°ú ¼­ºí¸´ ÄÁÅ×À̳ʸ¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù) ÀÌ·± »óȲ¿¡¼­ AWS Lambda°¡ ¼­ºí¸´ ÄÁÅ×ÀÌ³Ê Èä³»¸¦ ³»Áö ¾ÊÀ¸¸é, À¥ ÇÁ·¹ÀÓ¿öÅ©µéÀÌ ¿Ã¹Ù¸£°Ô µ¿ÀÛÇÏÁö ¾ÊÀ» °ÍÀÌ ´ç¿¬ÇÏ´Ù.

Vert.xµµ ¼­ºí¸´°ú ¼­ºí¸´ ÄÁÅ×ÀÌ³Ê ¾øÀÌ HTTP ±â¹Ý ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µé ¼ö ÀÖÀ¸³ª, ¼º°ÝÀÌ ´Ù¸¥ ÇÁ·¹ÀÓ¿öÅ©¶ó°í »ý°¢Çؼ­ ¹èÁ¦Çß´Ù.

Çѵ¥, ¸¶ÀÌÅ©·Î¼­ºñ½º(Microservices)¸¦ À̾®¾×Ƽºê(Reactive)¶ó´Â °³³äÀ» Áß½ÉÀ¸·Î ÀÚ¹Ù ¼¼»óµµ ºü¸£°Ô º¯ÇÏ°í ÀÖ´Ù. ¹Ù·Î ¼­ºí¸´°ú ¼­ºí¸´ ÄÁÅ×À̳ʸ¦ »ç¿ëÇÏÁö ¾Ê°í, HTTP ±â¹Ý ¾ÖÇø®ÄÉÀ̼ÇÀ» °³¹ßÀ» Áö¿øÇϴ Ratpack°ú Spring WebFlux¿Í °°Àº ÇÁ·¹ÀÓ¿öÅ©µéÀÌ´Ù.

Spring WebFlux framework

Spring WebFlux´Â Spring Framework 5¿¡ Æ÷ÇÔµÈ »õ·Î¿î À¥ ¾ÖÇø®ÄÉÀÌ¼Ç ÇÁ·¹ÀÓ¿öÅ©´Ù. ±âÁ¸ Spring MVC ¸ðµ¨¿¡ ºñµ¿±â(asynchronous)¿Í ³Íºí·°Å· I/O(non-blocking I/O) 󸮸¦ ¸Ã±â·Á¸é ³Ê¹« Å« º¯È­°¡ ÇÊ¿äÇ߱⠶§¹®¿¡ ¸®¾×Ƽºê ÇÁ·Î±×·¡¹Ö(Reactive programming)À» Áö¿øÇÏ´Â »õ·Î¿î À¥ ÇÁ·¹ÀÓ¿öÅ©¸¦ ¸¸µé¾ú´Ù°í ÇÑ´Ù.

Spring MVC¿Í Spring WebFlux´Â ´ÙÀ½°ú °°Àº ±¸Á¶·Î µÇ¾î ÀÖ´Ù. (ÀÌÈÄ MVC¿Í WebFlux¶ó°í ºÎ¸£°Ú´Ù)

MVC´Â ¼­ºí¸´ ÄÁÅ×ÀÌ³Ê¿Í ¼­ºí¸´À» ±â¹ÝÀ¸·Î À¥ Ãß»óÈ­ °èÃþÀ» Á¦°øÇÏ°í, WebFlux´Â ¼­ºí¸´ ÄÁÅ×À̳Ê(Tomcat, Jetty) ¿Ü¿¡µµ NettyUndertow¿Í °°ÀÌ ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀÌ¼Ç ÇÁ·¹ÀÓ¿öÅ© À§¿¡¼­ HTTP¿Í ¸®¾×Ƽºê ½ºÆ®¸²(Reactive Streams) ±â¹ÝÀ¸·Î À¥ Ãß»óÈ­ °èÃþÀ» Á¦°øÇÏ°í ÀÖ´Ù.

MVC¿Í WebFlux µÑ´Ù @Controller, @RequestMapping ÇüÅ¿¡ @MVC ¸ðµ¨À» ±×´ë·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. WebFlux´Â Route FunctionsÀ̶ó´Â ÇÔ¼öÇü ÇÁ·Î±×·¡¹Ö ¹æ½Ä¿¡ ¸ðµ¨À» Ãß°¡·Î Á¦°øÇÑ´Ù.

¾Æ·¡ ¸µÅ©´Â Spring 5¿Í WebFlux¿¡ ´ëÇØ ´Ù·ç´Â ÄÜÆÛ·±½º ³ìÈ­º»ÀÌ´Ù.

SpringCamp 2017 - Reactive Spring (Spring 5 & Reactor)

SpringCmap 2017 - Spring WebFlux

AWS Lambda¿¡´Â ¼­ºí¸´°ú ¼­ºí¸´ ÄÁÅ×À̳ʸ¦ »ç¿ëÇÏÁö ¾Ê´Â WebFlux ±â¹Ý¿¡ À¥ ¾ÖÇø®ÄÉÀ̼ÇÀÌ ´õ ÀûÇÕÇÏ´Ù°í º¸ÀδÙ.

WebFlux´Â ¾î¶»°Ô µ¿ÀÛÇϳª?

MVC´Â ´ÙÀ½°ú °°ÀÌ ¿äû°ú ÀÀ´äÀ» ó¸®ÇÏ°í ÀÖ´Ù.

http://terasolunaorg.github.io/guideline/1.0.1.RELEASE/en/Overview/SpringMVCOverview.html

¼­ºí¸´ ÄÁÅ×À̳ʷΠµé¾î¿Â ¿äûÀÌ DispatcherServlet¿¡°Ô Àü´ÞµÇ¸é, DispatcherServlet´Â ¼øÂ÷ÀûÀ¸·Î HandlerMapping, HandlerAdapter¿¡°Ô ¿äû 󸮸¦ À§ÀÓÇÏ°í, ViewResolver¿¡°Ô ÀÀ´ä ó¸®À» À§ÀÓÇÑ´Ù.

WebFluxµµ Å©°Ô ´Þ¶óÁöÁø ¾Ê´Â´Ù. ó¸® È帧À» °£´ÜÇÏ°Ô µµ½ÄÈ­Çؼ­ º¸¸é ¾Æ·¡¿Í °°´Ù.

À¥ ¼­¹ö(¼­ºí¸´ ÄÁÅ×À̳Ê, Netty, Undertow)·Î µé¾î¿Â ¿äûÀÌ HttpHandler¿¡°Ô Àü´ÞµÇ¸é, HttpHandler´Â Àüó¸® ÈÄ WebHandler¿¡°Ô 󸮸¦ À§ÀÓÇÑ´Ù. WebHandler ³»ºÎ¿¡¼­´Â HandlerMapping, HandlerAdapter, HandlerResultHandler 3°¡Áö ÄÄÆ÷³ÍÆ®°¡ ¿äû°ú ÀÀ´äÀ» ó¸®ÇÑ´Ù. 󸮰¡ ³¡³ª¸é HttpHandler´Â ÈÄó¸® ÈÄ ÀÀ´äÀ» Á¾·áÇÑ´Ù. HandlerMapping, HandlerAdapter´Â MVC°¡ »ç¿ëÇÏ´Â ÄÄÆ÷³ÍÆ®¿Í ¿ªÇÒ°ú À̸§ÀÌ °°Áö¸¸, µ¿ÀÛ ¹æ½ÄÀÌ ´Ù¸£±â ¶§¹®¿¡ º°µµÀÇ ÀÎÅÍÆäÀ̽º¸¦ »ç¿ëÇÑ´Ù.

MVC:

  • org.springframework.web.servlet.HandlerMapping
  • org.springframework.web.servlet.HandlerAdapter

WebFlux:

  • org.springframework.web.reactive.HandlerMapping
  • org.springframework.web.reactive.HandlerAdapter

MVC¿Í ´Ù¸¥ Á¡Àº ÀÀ´äÀ» ó¸®ÇÏ´Â ÄÄÆ÷³ÍÆ®°¡ HandlerResultHandler¶ó´Â °ÍÀÌ´Ù. HandlerResultHandler´Â ¸î °¡Áö ±¸Çöü°¡ Á¦°øµÇ´Âµ¥, ±× Áß ViewResolver¸¦ »ç¿ëÇÏ´Â ViewResolutionResultHandler°¡ ÀÖ´Ù.

Lambda¿¡¼­ Spring WebFlux¸¦ »ç¿ëÇϱâ

API Gateway¿Í Lambda¸¦ ÅëÇÕÇÏ´Â ¹æ¹ýÀº AWS °¡ÀÌµå ¹®¼­ÀΠSet up API Gateway Proxy Integration¿¡ ³ª¿Í ÀÖ´Ù. Áß¿äÇÏ°Ô Ã¬°ÜºÁ¾ß ÇÒ ºÎºÐÀº API Gateway¸¦ Åë°úÇØ Lambda Çڵ鷯°¡ ½ÇÇàµÉ ¶§ ÀԷµǴ °ªÀÎ 'Input Format of a Lambda Function for Proxy Integration'°ú Lambda Çڵ鷯 ½ÇÇà °á°ú°ªÀ¸·Î API Gateway¿¡°Ô ¹ÝȯÇÒ 'Output Format of a Lambda Function for Proxy Integration' ÀÌ´Ù. Áï, ¿äû°ú ÀÀ´ä ¸Þ½ÃÁö ÇÁ·ÎÅäÄÝÀÌ´Ù.

WebFlux¿¡ ÁøÀÔÁ¡ÀÎ HttpHandler ÀÎÅÍÆäÀ̽º¸¦ »ìÆ캸¸é, Lambda¿¡¼­ WebFlux¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀÌ º¸ÀδÙ.

import reactor.core.publisher.Mono;

public interface HttpHandler {

	/**
	 * Handle the given request and write to the response.
	 * @param request current request
	 * @param response current response
	 * @return indicates completion of request handling
	 */
	Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);

}

API Gateway¿¡¼­ µµÂøÇÑ ÀԷ°ªÀ» ServerHttpRequest·Î º¯È¯ÇÏ°í, ºñ¾îÀÖ´Â ServerHttpResponse¿Í ÇÔ²² HttpHandler¿¡°Ô ³Ñ±ä ÈÄ ¿äû ¹× ÀÀ´ä 󸮰¡ ³¡³ª¸é, ServerHttpResponse¸¦ °¡°øÇؼ­ API Gateway°¡ ¿øÇÏ´Â ÇüÅ·Π¹ÝȯÇØÁÖ¸é µÈ´Ù.

´Ü¼øÇÏ°Ô µ¿ÀÛÇÏ´Â ¼öÁØ¿¡¼­ API Gateway, Lambda, WebFlux¸¦ ¿¬µ¿Çϱâ À§ÇØ 4°¡Áö ¸ðµ¨ Ŭ·¡½º¸¦ ÀÛ¼ºÇß´Ù.

  • APIGatewayProxyRequest
  • APIGatewayProxyResponse
  • SimpleAPIGatewayProxyServerHttpRequest
  • SimpleAPIGatewayProxyServerHttpResponse

À§ 2°³ ¸ðµ¨Àº API Gateway, Lambda¸¦ ¿¬µ¿ÇÏ°í, ¾Æ·¡ 2°³ ¸ðµ¨Àº WebFlux¿Í ¿¬µ¿Çϱâ À§ÇØ ÀÛ¼ºÇÑ ¸ðµ¨ÀÌ´Ù. 4°³ ¸ðµ¨ Ŭ·¡½º¸¦ »ç¿ëÇؼ­ ¿äû°ú ÀÀ´äÀ» ó¸®ÇÏ´Â °£´ÜÇÑ ¼­¹ö¸®½º ¾ÖÇø®ÄÉÀ̼ÇÀ» ÀÛ¼ºÇغ¸¸é ¾Æ·¡¿Í °°´Ù.

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;

import serverless.aws.model.APIGatewayProxyRequest;
import serverless.aws.model.APIGatewayProxyResponse;
import serverless.aws.springframework.http.server.reactive.SimpleAPIGatewayProxyServerHttpRequest;
import serverless.aws.springframework.http.server.reactive.SimpleAPIGatewayProxyServerHttpResponse;


public class SimpleServerlessApplication implements RequestHandler<APIGatewayProxyRequest, APIGatewayProxyResponse> {

    @Override
    public APIGatewayProxyResponse handleRequest(APIGatewayProxyRequest proxyRequest, Context context) {
        APIGatewayProxyResponse proxyResponse = new APIGatewayProxyResponse();

        ServerHttpRequest request = SimpleAPIGatewayProxyServerHttpRequest.of(proxyRequest);
        ServerHttpResponse response = SimpleAPIGatewayProxyServerHttpResponse.of(proxyResponse);

        HttpHandler httpHandler = createHttpHandler(context);
        httpHandler.handle(request, response).block();

        return proxyResponse;
    }

    protected HttpHandler createHttpHandler(Context context) {
        return RouterFunctions.toHttpHandler(
            route(path("/"), request -> ok().syncBody("Hello, WebFlux!!!"))
        );
    }

}

¿øÇÏ´Â ÇüÅ·Πµ¿ÀÛÇÏ´ÂÁö È®ÀÎÇغ¸±â À§ÇØ °£´ÜÇÑ ¹æ¹ýÀº HttpHandler¸¦ »ý¼ºÇß´Ù. ÀÛ¼ºÇÑ ¾ÖÇø®ÄÉÀ̼ÇÀ» Lambda¿¡ ¹èÆ÷ÇÏ°í, API Gateway¸¦ ÅëÇØ Å×½ºÆ®Çغ» °á°ú´Â ±â´ëÇß´ø´ë·Î Àß µ¿ÀÛÇÑ´Ù.

½ÇÁ¦ ¼­ºñ½ºÇÏ´Â ¼öÁØ¿¡ ¾ÖÇø®ÄÉÀ̼ÇÀº ÀÌ·¸°Ô ´Ü¼øÇÏÁö ¾Ê´Ù. µ¥ÀÌÅͺ£À̽º¸¦ ºñ·ÔÇÑ ¿©·¯ ¼­ºñ½º ÄÄÆ÷³ÍÆ®µé°ú ÄÁÆ®·Ñ·¯µé·Î ±¸¼ºµÉ °ÍÀÌ´Ù. Spring Boot ±â¹Ý¿¡ ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µé°í ½Í´Ù¸é ¾î¶»°Ô ÇØ¾ß Çϴ°¡?

¹æ¹ýÀº Å©°Ô ´Ù¸£Áö ¾Ê´Ù. ¾Æ·¡¿Í °°ÀÌ Spring Boot ±â¹Ý¿¡ ¾ÖÇø®ÄÉÀÌ¼Ç ¼³Á¤ Ŭ·¡½º¸¦ ÀÛ¼ºÇÏ°í, SpringApplicationÀ» »ý¼º ÈÄ HttpHandle¿¡°Ô ¿äû°ú ÀÀ´äÀ» À§ÀÓÇÏ°í, ±× °á°ú¸¦ ¹ÝȯÇÏ¸é µÈ´Ù.

@SpringBootConfiguration
@Import({ JacksonAutoConfiguration.class
        , HttpMessageConvertersAutoConfiguration.class
        , CodecsAutoConfiguration.class
        , ReactorCoreAutoConfiguration.class
        , WebFluxAutoConfiguration.class
        , HttpHandlerAutoConfiguration.class
        , PlayerWebConfiguration.class })
public class ServerlessWebApplicationConfiguration {

    @Bean
    public WebFluxConfigurer webFluxConfigurer() {
        return new WebFluxConfigurer() {
            @Override
            public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
                builder.fixedResolver(MediaType.APPLICATION_JSON);
            }
        };
    }

    @Bean
    public RouterFunction<ServerResponse> rootHandler() {
        return route(path("/"), request -> ok().syncBody("Hello, WebFlux!!!"));
    }

}

public class LambdaEntryPoint implements RequestHandler<APIGatewayProxyRequest, APIGatewayProxyResponse> {

    @Override
    public APIGatewayProxyResponse handleRequest(APIGatewayProxyRequest proxyRequest, Context context) {
        APIGatewayProxyResponse proxyResponse = new APIGatewayProxyResponse();

        ServerHttpRequest request = SimpleAPIGatewayProxyServerHttpRequest.of(proxyRequest);
        ServerHttpResponse response = SimpleAPIGatewayProxyServerHttpResponse.of(proxyResponse);

        HttpHandler httpHandler = createHttpHandler(context);
        httpHandler.handle(request, response).block();

        return proxyResponse;
    }

    protected HttpHandler createHttpHandler(Context context) {
        SpringApplication application = new SpringApplication();
        application.addPrimarySources(Collections.singleton(ServerlessWebApplicationConfiguration.class));
        application.setWebApplicationType(WebApplicationType.REACTIVE);
        application.setApplicationContextClass(GenericReactiveWebApplicationContext.class);

        ApplicationContext applicationContext = application.run();

        return applicationContext.getBean(HttpHandler.class);
    }

}

·ÎÄÿ¡¼­ Å×½ºÆ®ÇÏ°í ½Í´Ù¸é, ¾Æ·¡¿Í °°ÀÌ HttpHandler¿¡°Ô À¥ ¼­¹ö¸¸ Á¦°øÇØÁÖ¸é µÈ´Ù.

@SpringBootConfiguration
@Import({ ServerlessWebApplicationConfiguration.class, ReactiveWebServerAutoConfiguration.class })
public class LocalEntryPoint {

    public static void main(String[] args) {
        SpringApplication.run(LocalEntryPoint.class, args);
    }

}

ÀÌÂë¿¡¼­ ³¡³»±â¿£ ¾Æ½¬¿ö¼­ ¸î °¡Áö Äڵ带 ´õ ³Ö°í »ùÇà ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µé¾îº¸¾Ò´Ù. ÁÁÀº ÇüÅ´ ¾Æ´ÏÁö¸¸, WebFlux Äڵ尡 ±Ã±ÝÇÑ ºÐµé¿¡°Õ ±¸°æ°Å¸® Á¤µµ´Â µÉ °ÍÀÌ´Ù.

¸¶¹«¸®

ÇØ°áÇØ¾ß ÇÒ ¹®Á¦µéÀÌ ¸î °¡Áö ÀÖ±â´Â ÇÏÁö¸¸, ÇÁ·ÎÅäŸÀÌÇÎÀ» ÅëÇØ ¾òÀº °ÍµéÀº ¸¸Á·½º·´´Ù.

¼­¹ö¸®½º°¡ ÁÖ´Â ÀÌÁ¡Àº ²Ï ¸Å·ÂÀûÀÌÁö¸¸, ¸¶Æ¾ ÆÄ¿ï·¯ ¾ÆÀú¾¾ÀÇ ±Û¿¡¼­Ã³·³ ¼­¹ö¸®½º °ü·Ã µµ±¸µéÀº ¾ÆÁ÷ ¼ºÀå±â¿¡ ÀÖ´Ù. ƯÈ÷ Cold start ¿Í ¸ð´ÏÅ͸µ¿¡ ´ëÇÑ ºÎºÐÀº ¸íÈ®ÇÑ ÇعýÀÌ º¸ÀÌÁö ¾Ê°í ÀÖ´Ù. ÀÌ´Â AWS¸¦ ºñ·ÔÇØ Google, Azure µîÀÌ Á» ´õ Èû³»¼­ ´Þ·ÁÁֱ⸦ ¹Ù¶ó°í ÀÖ´Ù.

WebFlux´Â °¡º±°Ô Á¢±ÙÇؼ­´Â ²Ï ¼ÕÇغ¼ ŸÀÔÀÌ´Ù. MVC´Â °ß°íÇÑ À¥ ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µé±â À§ÇÑ ¿©·¯ ÀåÄ¡°¡ ÁغñµÇ¾î ÀÖ¾î ÇÊ¿ä¿¡ µû¶ó ´Ù¾çÇÑ ÇüÅÂÀÇ À¥ ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µé ¼ö ÀÖÀ» ¼º¼÷ÇÑ ¸ðµ¨ÀÌÁö¸¸, WebFlux´Â ÀÚ·áµµ ¸¹Áö ¾Ê°í, È®ÀåÇϱ⠾î·Á¿î ±¸°£µéÀÌ ÀÖ¾î ÀÔ¸À´ë·Î À¥ ¾ÖÇø®ÄÉÀ̼ÇÀ» ±¸¼ºÇÏ´Â °Ô ½±Áö ¾Ê¾Ò´Ù.