Apache HttpResponse, HttpEntity 관련 주의 사항 Computer Code

Apache HttpComponent를 사용해서 HttpResponse를 처리할 때, HttpEntity는 반드시 처리해주어야 한다.
HTTP Request 요청만 보내고 Response를 처리할 필요가 없는 경우, 불필요하다 생각해서 Entity를 처리하지 않는 경우가 있는데 이런 사용법은 지양해야 한다.

아래와 같이 HttpClient, HttpContext 인스턴스를 재사용할 경우에는 반드시 response1의 entity를 처리해주어야 한다.
그렇지 않으면 다음 HTTP Request시에 Hang이 걸리는 문제에 맞닥뜨릴 수 있다. 

...
HttpGet httpget1 = new HttpGet(myUrl);
HttpResponse response1 = httpclient.execute(httpget1, httpcontext);

EntityUtils.consume(response1.getEntity()); // 필요함.

HttpGet httpget2 = new HttpGet(myUrl2);
HttpResponse response2 = httpclient.execute(httpget2, httpcontext);
...


HttpEntity는 내부에 열려진 스트림이 열린 상태로 존재하고, 스트림은 스트림 자체가 닫히지 않거나 ConnectionManager의 연결이 닫히지 않는 이상 계속 열려있게 된다. 이는 서버와의 연결도 계속 유지되고 있다는 뜻이고, 결국 서버당 연결 수 제한에 걸리면 추가 요청은 블럭될 수 밖에 없는 것이다. - 멀티스레드 상황에서는 더욱 주의해야 한다.

물론, HttpClient 를 재사용하지 않고 한 번만 HTTP Request를 호출하고 연결을 닫는 경우라면 특별히 문제될 것은 없지만, 그렇더라도 HttpEntity는 처리해주는 것이 바람직하다.

Hashed access, tagging pattern Computer Code

분산 노드에 데이터를 저장하고 읽는 방식에는 여러가지가 있지만, 결론적인 측면에서는 아직 CAP 를 벗어나지 못한다.
몇 가지 trade-off 들은 감수할 수 밖에 없고, 그 안에서 최대한 활용도를 극대화하는 게 아직까지는 최선이 아닐까 싶다.

hgLock에서 접근하는 방식 중 Hashed access, tagging pattern은 다음 상황을 위해 고려된 부분이다.
제한된 상황을 위한 고려이므로 데이터 모델과 처리 방식이 다른 상황에서는 당연히 맞지 않을 수 있다.

원래는 다른 noSQL에 넣으려고 하다 (당연하겠지만) 성능상 차별 포인트가 없어서, 지금은 용도를 전환하여 global lock쪽으로 이래저래 적용중..
-

전제는 어떤 데이터가 기록되었을 때, 모든 노드가 그 데이터를 필요로 하지는 않는다는 것이다.
많은 경우 단시간 내에 특정 데이터를 필요로 하는 노드 수는 전체 노드 수보다 적으며, 데이터에 접근하는 노드를 명확하게 제어할 수 있다면 성능을 적게 희생하면서도 consistency를 확보하는 데 도움이 된다.

다른 솔루션들과 비슷하게 hgLock 역시 데이터의 hash를 키로 데이터에 접근한다. 그리고 이 hash에 어느 어느 노드에 동기화가 되었는지를 나타나는 플래그가 추가(tagging)되어 있는데, 이 플래그를 가지고 데이터를 읽어올 노드를 판단하게 된다. - 실제 구현은 이 부분이 빡셈...

기본적으로 hash를 key-nodes에 배포하는 방식은 consistency-write 모델이며, value-node배포/tagging 값 변경은 eventually consistency를 따른다. 장점은 읽기와 쓰기 비율이 비슷한 상황에서 어느 정도의 CaP를 확보할 수 있지만, 단점으로는 플래그 업데이트를 위한 오버헤드와 데이터에 변경이 자주 일어나는 상황에서는 맞지 않다는 것.



IHttpModule.Init() 메소드는 여러번 호출될 수 있다. Computer Code

경험있는 개발자들은 이미 어떻게든 알고 있는 이슈이지만 정리차원에서 남겨본다.
자세한 내용은 아래 링크를 참고할 것.

요약을 하자면,

- 필요에 따라 HttpApplication 인스턴스는 여러 개가 생성될 수 있다.
- HttpApplication 인스턴스가 생성될 때 IHttpModule 또한 같이 생성된다. (정확하게는 HttpApplication 인스턴스가 Context 연결이 될 때 IHttpModule 또한 초기화가 된다.)
- IHttpModule이 생성될 때 IHttpModule.Init() 메소드도 호출된다.


왜 이런 점을 고려해야 하는가?

가장 문제가 되는 경우는 Init() 메소드에서 비용이 큰 작업을 할 때이다. 
HTTP 요청 상황에 따라 HttpApplication 인스턴스가 수 십 개도 생길 수가 있는데, 그만큼 Init() 메소드도 호출이 된다는 점을 고려해야 한다.

IHttpModule은 IIS가 떠 있는 동안 계속 존재하는 것이 아니다. 응용프로그램풀이 재생(Recycle) 될 때 다시 만들어질 수도 있고, 다른 이유로 언제든지 생성되었다가 해제될 수 있다. 또한 IHttpModule이 살아있는 시간도 보장되는 것이 아니기에, Init() 메소드에서 별도의 스레드를 생성하는 식의 비동기 작업은 안하는 것이 좋다. 

만약 IHttpModule의 상태값이나 환경설정값을 저장해야 한다면 static 변수를 사용하거나 HttpApplicationState를 사용하는 편이 좋다. 예를 들어 웹페이지 카운터값을 저장한다면, IHttpModule내에 멤버변수를 사용하면 안되고 static 멤버 변수나 HttpApplicationState에 저장을 해야 한다는 의미이다.
또한 static 변수나 HttpApplicationState에 저장된 값은 Application Pool이 유지되는 동안에는 계속 유지되지만, 이 역시 Application Pool이 재생되거나 재시작되면 리셋될 수 있다는 점을 염두에 두어야 한다. 


1 2 3 4 5 6 7 8 9 10 다음