관리 메뉴

취미개발 블로그와 마음수양

http와 스프링(6) - 정리와 궁상..토이플젝 적용할 부분과 앞으로의 블로깅? 본문

개발관련 잡다/HTTP

http와 스프링(6) - 정리와 궁상..토이플젝 적용할 부분과 앞으로의 블로깅?

아라한사 2019. 11. 22. 00:47

주의 : 본격 .. HTTP 스터디가 일단락 종료되어.. 야밤의 혼잣말 떠들어보는 1인칭시점 궁시렁궁시렁.

정리 감성 기술블로깅

(시리즈물인데 글마다 문체가 다른 듯;;)

야밤의 졸리지만 술취한 듯한 느낌으로 적으니, 틀린 점이 있다면 알아서 필터링해주세요^0^

 

시리즈목차

https://adunhansa.tistory.com/261

 

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

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

adunhansa.tistory.com

 

 

 

0. 시작하며 궁시렁궁시렁 - 아끼며 살자

이것이 스타트업이다 파멸편을 보면 .. 여러 스타트업의 불안요소중의 하나는 바로 치솟는 서버비가 아닐까합니다.

 

제 사주팔자가 초봄의 자라나는 나무팔자이다보니 모든 개발자 경력이 스타트업에서 이루어져서(...)

트래픽에 터져서 행복(?)해본 경험도 없거니와,

트래픽 많이 터지니 와보세요~ 해도 갈 생각도 없습니다만(?음?)

 

다만 스타트업과 서버비를 생각해보자니, 

잠시나마 AWS 인스턴스들을 운영하면서 나왔던 요금 고지서를 보며

바들바들 떨 때가 있었음을 생각해보면 그리 작은 돈은 아닐거라고 생각하고 있습니다.

 

HTTP 서적을 읽으며 들었던 생각은 제가 얼만큼 네트워크 비용을 아껴가며 개발을 하고 있었던 가에 대한 고민이었습니다. 

 

지인들을 위한 서버를 조금 운영중이던 입장에서, 최대한 여기저기 빌붙어 서버를 운영하고 있었고,

그런 서버들을 운영하며 비록 해외서비스이더라도 네트워크를 조금이라도 줄여보고자하는 게

얹혀살던 해외서비스들에 대한 미안함의 표현이랄까요... (깃헙 저장소..공간 많이 낭비해서 미안해요~)

 

그리고 혹시나 저와 같은 욕심을 하실지도 모를 분들과 함께 고민을 나누고자(^^ 도와줘요 지나가는 고수님~)

그냥 주저리주저리 적어보는 블로깅..

 

1. HTTP 메서드에서의 멱등성과 안전성


개발자는 이런저런 스펙문서를 적으면서 이것이 이것이오 해야 좀 있어보이는 듯한데(-_ -)

그런 느낌으로 적어보자면  HTTP 1.1 를 다루고 있는 RFC 2616 (구버젼) 에는

다음과 같이 HTTP 메서드의 안전성과 멱등성에 대해서 이야기를 하고 있습니다.

 

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

 

HTTP/1.1: Method Definitions

part of Hypertext Transfer Protocol -- HTTP/1.1 RFC 2616 Fielding, et al. 9 Method Definitions The set of common methods for HTTP/1.1 is defined below. Although this set can be expanded, additional methods cannot be assumed to share the same semantics for

www.w3.org

HTTP 1.1 메서드에서 2616에는 다음과 같이 8개가 있습니다.

5789 RFC 에서 9번째에서 PATCH가 나왔다고 하는데..뭐 메소드 정의에서는 바로 알아보고 싶진 않습니다만(...)

 

https://developer.mozilla.org/ko/docs/Web/HTTP/Methods

 

멱등성과 안전성을 잠시 보자면..

 

결국 여기서 멱등성(Idempotent)이라는 것은 몇번을 실행해도 같은 결과를 보장한다는 것이겠구나 싶습니다?!
GET 요청만 봤을 때 GET은 멱등하다고하는데 다만 조회수가 올라가는 것을 생각해보면?

뭐 실제로는 정말 순수하게 GET 멱등할까하는 생각이 좀 들긴하네요!?

 

https://padawanr0k.github.io/2018/06/23/etc/Idempotent/

 

개발용어로서 멱등성(Idempotence)이란? - R0K의 공부블로그

멱등성(Idempotence)이란? 멱등성이은 동일한 동사를 두번 사용해도 리소스에는 아무런 변화가 없음을 의미한다. HTTP 메소드를 예를 들자면, GET, PUT, DELETE는 같은 경로로 여러번 사용해도 결과가 같다. 하지만 POST같은 경우는 새로운 데이터가 생성되는 것이기 때문에 멱등이아니다. GET : 리소스의 표현을 반환하기 위해 사용한다. 멱등성 POST : 새로운 리소스를 업로드하기위해 사용한다. 멱등성이 없다 PUT : 기존의 리소스를

padawanr0k.github.io

 

스터디구성원분께서 얘기하여주시길 웹헌장에서 모든 리소스의 URI 에서는 유일해야된다 이런 얘기를 해주신듯한데

멋있게 다시 적을려니 문맥만 기억나고 정확한 디테일이 기억이 가물가물합니다^^;; 후 ㅠ

 

뭐.. 그러한 URI 에 대한 멱등성이 있다는 것은 즉 다시 접속했을 때

네트워크 데이터를 다시 요청하지 않아도 되는 조건부요청, 캐쉬 가능성cachable 을 말할 수 있겠는데,

 

하지만 역시 우리가 사는 세상은 아름답지 않은 것이, 배포도 다시 해야되고

올렸던 정보들도 수정해야하는 등의 그에 따른 리소스 변경도 일어난다는 것이다

이렇게 변경될 수 있는 정보들을 어떻게 캐시할 것인가?

그리하야 LastModified, eTag, CacheControl 등등의 여러 캐시가능한 방법이 나왔다고 합니다?!

 

2. 그간의 정리와 욕심?

 

책을 읽으면서 저의 시골마을같은 한적한 빈집 서버에서

이런저런 놀이정도로 적용해볼만한 것들을 적어보자면... 

 

2.1 압축

1. 블로깅을 시작하면서 잘 해보지 않았던 브로틀리인코딩등을 조금 해보았습니다.

 

TODO : 나중에 좀 더 시간짬이 되면 그래들 빌드할 때 자동으로 brotli encoding , gzip 인코딩을 걸면서 정적리소스들을 압축시켜주는 task 를 한번 돌려보고 싶긴합니다. (다른 분이 해주셔도 감사함 ㅠ!)

 

2.2 관심사(?)의 분리와 캐시

그리고 해봤던 일들이 API 들을 LastModified 와 eTag 로 캐시해보기 고민해보고

eTag를 이용하여 view 까지 304로 해봤던 일이었습니다.

 

오늘 왔던 손님을 내일 다시 올때는 빈손으로 돌려보내드리자.

 

그리고 결국 5번째 글에서 적었지만

https://adunhansa.tistory.com/260?category=737877

 

결론적으로 들었던 생각은 

어떤 특정 데이터를 보여주는 페이지가 있다고 했을 때, 

캐시 히트를 위하여 각각의 영역 관심사별로 별도 분리를 해보는 일이었습니다.

 

캐시 이야기 (5번 적중쪽)

https://feel5ny.github.io/2019/09/30/HTTP_007-1/

 

캐시의 개념과 장점

캐시는 자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치다.웹 요청이 캐시에 도착했을 때, 캐시된 로컬 사본이 존재한다면,그 문서는 원서버가 아니라 캐시로부터 제공된다. 불필요한 데이터 전송을 줄여서, 네트워크 요금으로 인한 비용을 줄여준다. 캐시는 네트워크 병목을 줄여준다. 대역폭을 늘리지 않고도 페이지를 빨리 불러올 수 있게 된다. 캐시는 원

feel5ny.github.io

 

 

게시글 목록이 바뀌었다고, 데이터와 껍데기 HTML 까지 을 전부 내려주는 것도 뭔가 낭비같고

보통은 게시글을 캐시해서 보여주다가 데이터가 변경되면 게시글 목록만 API형태로 내려주고

HTML 페이지는 또 HTML 페이지만 캐시하고 있다가 변경되면 HTML만 다시 내려주는 형태를 생각해보았습니다.

 

2.3 욕심 

 

좀 더 나아가서 스타일시트나 JS도 뭔가 버져닝을 따로 했다가 API에 버져닝정보를 물어보고 보여주면 어떨까하는 생각이 들긴하였네요. 위의 2단계구조에서 3단계구조 변신?!

 

script data-src 형태로 뿌려서 주소 파싱하던가하는.. ? 

최근에 스터디참여하는 코드스피츠( https://www.facebook.com/groups/codespitz/

넌블럭킹JS 에서 나왔던 이런저런 코드들을 적용해보면 어떨까하는 생각도 들긴한데

당장 이것은 욕심같습니다 ㅠ

 

페이지따로, API 따로, 정적자원도따로(욕심)

 

윗 클라이언트 서버의 그림을 보았을 때.. 결국 이런저런 일을 하면서

첫 접속은 화려하게. 그 이후 접속은 심플하게..할 수 있지 않을까 하는 잡생각이 들었던 순간입니다.

 

(판매용 이모티콘이라 링크를 같이 첨부 : https://e.kakao.com/t/a-demanding-client 화려하면서 심플하게 해..해볼수는 있다.규?)

 

이것말고도 HTTP 를 공부하다보면 나오는 델타인코딩이라는 개념이 있었는데,

자세히 안 보았지만 변경된 부분만 보여주는 개념인 듯합니다만

단순한 게시글 목록을 클라이언트단에서 저장한다고 했을 때 증가한 만큼만 가져오면 되지 않을까!? 하는 약간의 잡생각이 들긴 하였네요..크흠. 

https://m.blog.naver.com/PostView.nhn?blogId=fleshmeat&logNo=120041673425

 

HTTP Delta Encoding

원저자 : Jeffrey C. Mogul (mogul@pa.dec.com) Compaq Computer Corporation Western Research L...

blog.naver.com

 

3. 아직 안 다뤄본 무궁무진한 영역들과 욕심..?

 

3.1 프록시 캐시

아무튼 여기까지 했는데, 5번까지 적고서 아직도 못 적은게 많습니다.

클라와 서버사이에 프록시가 낀 경우에는 어떻게 될까?

이에 대비할 수 있는 많은 헤더옵션이 있었는데 제대로 본 것이 없습니다ㅠ

proxy가 구형라우터같은 장비라면 무슨 일이 일어날까요?!

 

3.2 eTag 등의 좀 더 심화

 

그리고  지금까지 블로깅하면서 서버에서 eTag 만 내렸지 딱히 화면단에서는 뭘 한 것이 없는데 알아서 캐시가 되었습니다.  이것은 무슨 마법일까요!?!

아직 eTag 관련 헤더도 내용을 적은게 없고 잠시 검색해보니 나오는 약한 eTag, 412 충돌.. 이런 것도 적은게 없습니다. ㅠ

알아야할게 많군요 흠 ㅠ 'ㅁ'

 

3.3 헤더폭발에 따른 HTTP2

스터디원분의 조언에 따르면, 저렇게 캐시를 할 것등을 나누고 하다보면 요청이 늘어나게 되는데

그렇게 되면 요청마다 헤더내용이 엄청 많아지게 되며 (사진은 리스펙트하는 스터디 대장님ㅠ)

 

그리하여 결국 HTTP2까지 가게된다고 합니다만.. 언제 다룰 수 있을지.. ㅠ.ㅠ 

 

 

3.4 백엔드 코드단에서의 간편하게 만들기

 

아마 5번째 블로깅보고, 저야 뭐 따로 지인플젝이니까 그러려니 하지만 

회사플젝에서 어떤 개발자분이 "아니 띠용 이런 것이?! 하면서 적용합시다..!?" 했다가는..

이런 개발자 유머상황을 맞이 하시지 않을까하는 걱정이 조금 듭니다.

 

신참이 프로젝트에 새 기능 추가를 제안할 때

 

회사마다 어느정도 생산성을 위한 프레임워크 위의 프레임워크, 혹은 유틸함수모음을 가지고 있을텐데

 

목표는 eTag를 붙여주기위한 ResponseEntity<T> 형 말고 그냥 어떤 일반객체/특정 타입으로 리턴하더라도, 

정해진 약속(?)같은 것에 따라서 eTag 같은 정보를 계산해서 주는 것을 만들어보고픈 욕심이 생기는 순간입니다. 

서버 프로파일에 따라서 그러한 기능의 on/off 를 하면 좀 더 좋을 것같긴합니다.

 

3.5 프론트단에서의 eTag manager

 

스터디에서의 조언대로 저의 토이플젝에서는 eTag를 좀 더 자세히 알아보고

화면단에서 eTag매니저를 가지게 될 것같습니다.

모든 네트워크 요청은 한 곳에서 모여서 처리를 하게 되면서

여기서의 eTag매니저에서 직접 캐시등을 관리하는 형태를 가져볼 듯합니다만..

언제 적을지 모르지만, 이런 저런 코드를 같이 적어보고는 싶습니다 ㅠ

 

3.6 TCP 이야기 약간

결국 HTTP 를 다루다보면 그 밑단 레이어인 TCP 영역을 뒤져보게 되었습니다만 ㅠ

틈틈이 이야기를 해볼지도..

 

3.7 HTTP2로 가면서 헤더압축을 API 에서 흉내내보기? 

 

HTTP2 의 특징중 하나로 ( HPACK : Header Compression ) 헤더압축을 들 수가 있습니다. 

위에서 5번까지 다루며, 캐시적중을 위하여 URL들이 분리가 되었던 점을 보실 수가 있는데,

그만큼 같은 요청이 많아지고 반복될 수 있는 헤더내용이 많아지게 되는 현상이 발생한다고 합니다. 

 

이를 HTTP2에서는 허프만 코딩이라는 방법으로 헤더압축을 통한다고 하였는데요. 

https://http2.tistory.com/1

 

HPACK에서 사용하는 Huffman coding

HTTP/2.0에는 핵심적인 기능 3가지가 있다. 1. HPACK : Header Compression 2. Multiplexing 3. Server push HPACK에서 Header압축을 하는 알고리즘으로 Huffman coding(혹은 Huffman code)을 활용한다 (HPACK에..

http2.tistory.com

https://b.luavis.kr/http2/http2-header

 

Luavis' Dev Story - RFC 7541(HTTP 2/HPACK) HPACK

http2의 header 압축표준 hpack

b.luavis.kr

HPACK의 인덱싱 테이블을 본 순간 아.. 저의 API 도 뭔가 기계친화적(?)이지 않다는 생각을 하였습니다.

 

이런 API 응답이 있다고 하면..

{
	"name": "arahansa"
    "address" : "incheon"
}
{
	"name": "saru"
	"address": "cheongju"
}

 

뭔가 서버단과 클라이언트단에서 위에서 개발했던 eTagManager 가 API 마다 어느정도 캐시를 가지고 있고, 

그 캐시된 내용중에 서버에서 제공하는 변수딕셔너리 테이블을 제공하면

 

{
	"1": "arahansa",
    "2" : "incheon"
}
{
	"1": "saru"
	"2": "cheongju"
}

모든 API에서 변수테이블을 가지고 있다면

이렇게도 요청과 응답을 바꿔볼 수 있지 않나하는 생각이 드는 순간이었습니다.

 

아 보통의 개발자는 이러한 인코딩 과정을 모르고 그냥 일반 변수로 사용을 하고 네트워크 요청단에서 인터셉터가 걸려서 인코딩되고 백엔드에서도 특정 커스텀 인코딩 헤더가 있으면 풀거나 압축해서 내려주는 형식..?!이랄까요

Content Encoding 을 커스터마이징 해볼수 있지 않을까요?!

desc1 , desc2 같은 경우는 d1, d2 로...? 크흠 ? 

 

etag manager 를 만들고나면 서버와 클라이언트 단에서 만들어볼 수도 있을 것같긴합니다.

 

4. 줄이며 

 

이밖에도 하다보면 엄청 다룰 내용들이 많아질 듯합니다만 개발하는 사람은 항상 바쁩니다.

개발도 해야되고, 새로 나오는 기술도 알아야되고, 책도 봐야되고

커피도 마시고, 잠도 자야됩니다. 

 

이렇게 좀 적으면서 서로 나누다보면 서로의 짐을 조금 덜 수 있지 않을까요?!

저도 지금 글 적는 순간이 밤인지라, 빨리 잘려고 이만 줄입니다

==3=3 

 

본격 스터디 HTTP편  끝난 김에 궁시렁 궁시렁블로깅..

 

(결국 http 완벽가이드와 다른 책들도 보기 시작하였군요..

http 스터디는 끝나고 틈틈이..취미로 혼자 조금씩 해보기로 합니다.

전 천천히일지라도 꾸준히 하는 편이니..(아마?)

)

 

혹시라도 이 글을 보실 스터디원분들께는,

많이 배웠고, 즐거운 시간이었습니다. 감사합니다~

 

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966261208&orderClick=LEa&Kc=

 

HTTP 완벽 가이드

『HTTP 완벽 가이드』는 HTTP 규약이 어떻게 작동...

www.kyobobook.co.kr

괜히 HTTP 블로깅한다고 해서..이 고생을..