모호한 버그 수정: Apache, GZip, ETags 및 Edge Compute

나는 최근에 Apache의 GZip 모듈과 EdgeWorkers 을 사용하는 영리한 솔루션의 모호한 성능 버그를 소개받았습니다. 그래서 동영상을 만들고 이를 다루는 작은 블로그 게시물을 만들었습니다.



내가 내 일에 대해 좋아하는 한 가지는 내가 작업에 전혀 관심이 없었던 일이나 기회에 대해 나보다 훨씬 더 똑똑한 사람들과 함께 일하게 될 때입니다.

예를 들어 Apache은 틀림없이 지구상에서 가장 인기 있는 HTTP 서버 기술이지만 결함이 없는 것은 아닙니다. bug reports을 뒤져보면 Hendrick Nordstrom이 2006년에 보고한 "Incorrect ETag on gzip:ed content"라는 것을 발견할 수 있습니다.

Hendrick은 mod_deflate 모듈을 사용하여 GZipped된 엔티티가 일반 엔티티와 동일한ETag을 전달하여 ETag 인식 프록시 캐시와 일종의 불일치를 일으키는 것을 발견했습니다.

익숙하지 않은 경우 ETag는 기본적으로 리소스의 특정 버전을 식별하는 데 사용되는 HTTP 응답 헤더입니다. ETag의 값은 종종 파일 내용이나 날짜 수정 또는 이 둘의 조합에서 생성된 해시 값입니다.

다음과 같이 보일 수 있습니다.

ETag: 27dc5-556d73fd7fa43


HTTP 요청에 기존 ETag 응답 헤더와 일치하는 헤더If-None-Match가 포함된 경우 프록시 캐시(예: CDN)는 파일이 변경되지 않았으며 304 "수정되지 않음"상태로 응답할 수 있습니다.

이론적으로 이것은 더 빠르고 대역폭을 절약합니다.

Apache에서 GZip 압축 모듈을 활성화하면 실제로 ETag에 대해 생성된 해시 값 끝에 작은 "-gzip"접미사가 추가됩니다.

안타깝게도 Apache가 If-None-Match 헤더("27dc5-556d73fd7fa43-gzip")를 ETag 값("27dc5-556d73fd7fa43")과 비교할 때 접미사를 설명하지 않습니다.

결과적으로 항상 전체 리소스 페이로드를 제공할 것입니다. ETag와 GZip이 이론상 대역폭을 절약하는 두 가지 방법이라는 점을 고려하면 아이러니합니다.

이 문제를 명확하게 설명할 수 있었으면 좋겠지만 그렇지 않은 경우 "Apache, ETag, and ‘Not Modified’"on Flameeyes’s Weblog 이라는 훌륭한 블로그 게시물이 있습니다. 솔루션을 제공하기도 합니다.

그렇다면 문제가 이미 해결된 것이라면 내가 오늘 이 이야기를 하는 이유는 무엇입니까?

솔루션을 사용하려면 Apache 구성을 수정해야 합니다. 하지만 요즘 개발자로서 우리가 스스로 할 수 없는 경우가 많다는 것을 너무 잘 알고 있습니다. 권한이 없거나 타사 서비스를 사용 중일 수 있습니다.

여기서 흥미로운 해결책이 나옵니다.

Akamai에는 EdgeWorkers이라는 제품이 있는데, 기본적으로 클라이언트와 원본 서버 사이에 위치하여 JavaScript 논리를 실행할 수 있습니다.

따라서 클라이언트가 요청을 하면 EdgeWorker는 요청을 가로채 원본 서버로 가는 도중에 수정할 수 있습니다. 또는 오리진 서버가 응답을 하면 Akamai EdgeWorker가 해당 응답을 가로채서 클라이언트로 다시 전달되기 전에 수정할 수 있습니다.

이론적으로 Apache 구성에 대한 액세스 권한이 없는 개발자는 Apache 구성 수준에서 솔루션을 해결할 수 있을 때까지 여전히 임시 수정을 원숭이 패치할 수 있습니다.

다음과 같이 보일 수 있습니다.

// Modify origin responses
export function onOriginResponse(request, response) {
  // Grab the server name
  const serverName = response.getHeader('Server')[0];
  // Grab the ETag header
  const etag1 = response.getHeader('ETag')[0];
  // Check if it's an Apache server and the ETag ends with '-gzip'
  if (serverName.startsWith('Apache') && etag1.endsWith('-gzip')) {
    // If so, strip out the '-gzip' suffix
    response.setHeader('ETag', etag1.replace('-gzip', ''));
  }
}


나는 이것이 실제로 많은 사람들에게 적용되지 않을 수도 있다는 것을 알고 있지만 모호한 버그, 심오한 기술 지식 및 수정해야 할 코드 몇 줄의 균형이 잘 맞기 때문에 공유하고 싶었습니다. 특히 Akamai EdgeWorkers 부분을 포함하면 이전에는 생각하지 못했던 멋지고 우아한 접근 방식입니다.

오늘 당장 귀하와 관련이 없더라도 흥미를 느끼셨기를 바랍니다.

읽어주셔서 정말 감사합니다. 이 기사가 마음에 드셨다면 . 나를 지원하는 가장 좋은 방법 중 하나입니다. sign up for my newsletter 또는 새 기사가 게시되는 시기를 알고 싶은 경우에도 할 수 있습니다.


austingil.com에 원래 게시되었습니다.

좋은 웹페이지 즐겨찾기