개발관련 잡다/HTTP

Http와 스프링 (3) : eTag를 이용하여 View 에도 적용하기

아라한사 2019. 11. 9. 20:33

목차

https://adunhansa.tistory.com/261

 

http와 스프링(0) - 연재를 시작하며..

운 좋게, 좋은 스터디원분들과 좋은 책을 만나 HTTP 스터디를 시작하며 다음의 연재글을 시작해보려고 합니다. 목차 http와 스프링 뒤적뒤적 연재 시리즈~ --- 1편 - Encoding - Brotli 적용해보기 https://adunha..

adunhansa.tistory.com

 


지난편에서 eTag 를 이용한 HTTP API 레벨단에서의 캐싱을 다루었습니다.

이번편에서는 eTag를 이용하여서 간단히 HTML View Rendering 을 다뤄보겠습니다.

 

0. 개요 : HTTP 응답코드와 HTTP캐시들 알기

바로 이전글의 eTag, HTTP상태코드를 보고 넘어가겠습니다. 

Http와 스프링 (2) :  LastModified, ETag 직접 쳐보기 https://adunhansa.tistory.com/256

 

 

1. 시나리오

혹은 확인해보고 싶은 일

 

HTTP API 레벨에서의 캐시가 된다는 것을 알았으니 개발자의 욕심은 뷰에서도 발동이 됩니다.

HTML 페이지가 렌더링되어서 응답이 뿌려지는데, 이게 항상 200 OK를 리턴하니..

HTML 페이지에도 eTag를 적용하여, 네트워크를 아끼고 싶은 욕심이 나게 됩니다. 

 

먼저 eTag, 캐시 관련하여 스프링 레퍼런스 사이트를 확인해봅니다.

검색해보니 다음과 같은 페이지가 나옵니다. 

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-caching-etag-lastmodified

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

(참고사항 : 레퍼런스 사이트에 eTag 이야기나오면서 409 PRECONDITION FAILED 라고 적혀진 부분이 있는데 오타입니다. PRECONDITION Failed 가 412 상태코드죠~

고칠려고 레퍼런스 github 을 뒤져봤는데 이미 수정반영되어져있고 배포가 안된듯하네요. 스프링 문서풀리퀘 건질 것이 없습니다 ㅠ )

예제코드는 대략 다음과 같습니다.

 

위의 스프링 코드를 참조해서 제쪽에서도 다음과 같이 코드를 적어주었습니다.

https://github.com/arahansa/learn_http_with_spring/blob/master/first/src/main/kotlin/com/arahansa/chapter2/EtagViewRenderController.kt

 

@Controller
@RequestMapping("/chap2")
class EtagViewRenderController {

    fun getEtag() : Long{
        return 1L
    }

    @GetMapping("/etagview")
    fun eTagTest(webRequest: WebRequest, name:String?, model: Model): String?{
        val eTag: Long = getEtag()
        if (webRequest.checkNotModified(eTag)) {
            println("여기서 eTag널처리하는 부분이 들어가긴하겠죠..")
            return null
        }
        model.addAttribute("name", name)
        return "chap2/etagview"
    }
}

 

1번은 getEtag() 부분은 어플리케이션 레벨에서 eTag를 계산하는 부분입니다.

테스트용 프로젝트라서 1L 로 계산하게 했는데,  작업자가 직접 변경해주거나 서버 첫 로딩때의 view 파일의 해시를 계산한다거나하는 작업을 할 수 있을 것이라 생각합니다. 

 

2번은 if(webRequest.checkNotModified(etag) 부분은 eTag를 체크하는 부분입니다. 

이부분에서 eTag를 체크해보고, 같은 etag라면 뷰를 렌더링하지 않고 304 수정되지 않음 상태코드 를 반환할 수가 있게 됩니다. 

 

3번은 model.add 부분은 그 이후의 계속적인 작업이라고 하네요 

 

2. 직접해보기

 

직접 해보기 테스트입니다. 윗 코드의 컨트롤러 주소에 다음과 같이 접속해보겠습니다 .

 

맨처음에는 200코드와 465b 가 나옵니다. 

 

그 이후 접속을 확인해보겠습니다. 

304 수정되지않음 상태코드와 함께 응답은 100b로 줄은 것을 확인할 수가 있습니다.

html 페이지가 내용이 많았다면 좀 더 극적인 사이즈 절감이 있을 거라 생각합니다.

 

 

일반 계속 200 던지는 페이지.. 

 

3. 결론과 추가 생각

 

1. CPU 계산을 줄이는 것은 아니지만, 네트워크 비용을 줄이자.

 

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#filters-shallow-etag

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

3-2 좀 더 생각해볼 수 있을 추가생각

 

3-2-1 동적 콘텐츠 캐싱에 대한 고민
(여기서도 적용해볼 수 있는 얘기지만, 바뀌지 않는 부분과 바뀌는 부분의 분리)
HTML 페이지가 캐싱이 된다면, 정적인 페이지부분은 캐싱하고

동적으로 내용을 채울 부분들은 API 호출로 채우면 되지 않을까? 

뭐 돈많은집 서버라면 그냥 200 - OK 하면 되겠지만..
홈서버나, 나같은 한푼한푼 아쉬운 개발자는?! 최대한의 캐시로 비용을 아껴야한다.


API 레벨로 내용을 채울, 동적으로 내용을 채우는 부분들도 매번 바뀌는 것이 아니므로
여기서도 HTTP API 레벨의 캐시를 적용하면 되지 않을까?

 

3-2-2  다국어 콘텐츠

Accept-Lanuage 로 콘텐츠 니고시에이션될 다국어페이지는 그렇다면 어떻게 캐시되나요?

등등의 생각을 해볼 수가 있겠습니다. 저도 일단 직접 테스트 해볼 거긴하구요. 

다음 포스팅에서 좀 더 생각해보겠습니다. 

 

3-2-3 엄밀히 말하자면..

엄밀히 말하자면 이번 eTag관련 뷰렌더링은 조금 더 알아볼 여지가 있습니다.

추후 포스팅하겠습니다..

 

감사합니다.