nyancoder

WWDC 2021 - Analyze HTTP traffic in Instruments 본문

WWDC/WWDC 2021

WWDC 2021 - Analyze HTTP traffic in Instruments

nyancoder 2021. 8. 17. 02:36

원본 영상: https://developer.apple.com/videos/play/wwdc2021/10212/

 

  • Instruments 13의 네트워크 템플릿에 포함된 새로운 HTTP 검사 도구를 사용하면 HTTP 트래픽을 검사할 수 있습니다.

  • 이 기능은 모든 Apple 기기에서 작동합니다.
  • HTTP/3 프로토콜 또는 VPN을 통해 전송된 트래픽 또한 포함됩니다.
  • 디스크 캐시 된 요청이나 네트워킹 에러 등을 포함한 결과를 표시합니다.
  • URLSessions 및 URLSessionTasks와 같은 상위 수준의 API 개념상에서 노출됩니다.

 

HTTP instrument UI overview

  • 주어진 시간에 추적에서 얼마나 많은 URLSession 작업이 실행되고 있었는지에 대해 표시됩니다.

  • 그 아래의 항목에서 프로세스별 활동 분석을 보여주며, 디버그 가능한 프로세스의 트래픽 외에도 그 프로세스에서 초기화된 백그라운드 프로세스의 트래픽도 검사할 수 있습니다.

  • 각 프로세스에는 해당 프로세스가 사용하는 모든 URLSession이 표시됩니다.
  • sessionDescription을 사용하면 이름을 지정할 수 있기 때문에 분석에 도움을 얻을 수 있습니다.

  • 트래픽은 요청된 도메인별로 분류되며, 이 항목에서는 작업과 각 트랜잭션을 포함한 작업에 대한 자세한 정보를 보여줍니다.

  • 도메인에서 데이터를 로드하는 예제를 보면 위와 같이 표시됩니다.

  • 이를 추상적인 방식으로 표시하면 위와 같습니다.
  • 최상위 에는 Task 개체가 있고 각 개체는 하나 이상의 트랜잭션으로 구성됩니다.
  • 트랜잭션은 HTTP 요청 응답의 쌍입니다.

  • Task를 만들고 resume을 호출하면 작업이 시작되며, 완료 블록이 호출되기 직전에 종료됩니다.

  • 각 작업 에는 taskDescription를 사용하여 이름을 지정할 수 있습니다.
  • 이 속성은 Instruments에서 레이블을 지정하는 데 사용됩니다.

  • 작업이 오류로 인해 완료되면, 오류 메시지가 표시됩니다.

  • 하나의 작업은 여러 트랜잭션으로 구성될 수 있습니다.
  • 위의 예제에서 apple.com을 로드하는 작업은 표준 url인 www.apple.com로 리다이렉션 응담을 받습니다.
  • 로딩 시스템은 처음에 apple.com에 대한 요청을 생성합니다. 잠시 후, 선호하는 URL이 실제로 www.apple.com임을 알리는 리디렉션 응답을 서버로부터 받습니다.
  • 리디렉션 규칙에 따라 301 응답을 반환하는 대신 새 트랜잭션이 기본 URL을 로드하여 응답으로 반환합니다.

  • 트랜잭션은 요청과 응답의 조합입니다.
  • URLSession이 작업을 처리하기 위해 수행하는 작업과 일치하며, 요청된 URL, 전송된 데이터에 대한 정보 등과 같은 HTTP 계층의 모든 정보를 포함합니다.

  • 트랜젝션 표시에서 요청과 응답이 있으며, 도메인 정보를 볼 수 있습니다.

  • 또한 요청 레이블에서 경로와 쿼리를 얻을 수 있습니다.

  • 요청에서는 HTTP 버전, HTTP 메서드, Authorization이나 Cookie 헤더를 보냈는지 여부가 표시됩니다.

  • 응답에서는 상태 코드, 응답에 쿠키가 포함되어 있는지 여부, 응답 의 콘텐츠 유형이 표시됩니다.

  • 요청 및 응답에 소요된 시간과 트랜잭션의 작업에 대한 타이밍 정보는 트랜잭션 상태에 의해 캡처됩니다.

  • 트랜잭션의 시작은 URL 시스템이 요청을 하기 위한 트랜잭션을 생성하는 시점입니다.
  • 그 이후 유효한 캐시가 있는지 확인하고 없는 경우에는 새 요청을 예약하려고 합니다.

  • 이 시점에서 트랜잭션은 사용 가능한 연결을 기다리면서 기다릴 수 있습니다.

  • 요청 전송 상태는 첫 바이트가 보내지기 시작할 때 시작해서 마지막 바이트를 네트워크로 보내면 끝납니다.

  • 트랜잭션은 응답 대기 상태가 됩니다.
  • 서버에서 응답이 오면 첫 번째 바이트를 수신할 때부터 마지막 바이트를 수신할 때까지 응답 수신 상태가 됩니다.

  • 시스템 이것이 성공적인 응답인지 판단하면 전체 트랜잭션이 완료됩니다.

  • 실제로는 캐시 조회나 전송 상태의 경우는 훨씬 더 짧기 때문에 위와 같이 나타날 가능성이 더 큽니다.

 

HTTP 성능 문제 분석 예제

  • 예를 들어 SNS 앱을 개발하는데 이미지를 로드하는데 시간이 걸릴 때, HTTP 트래픽 도구를 사용해 볼 수 있습니다.

  • Product - Profile을 선택하여 Network을 누르면 프로파일링이 가능합니다.

  • 프로파일링 기능의 첫 번째 HTTP Traffic은 기존 네트워크 연결 프로파일러입니다.
  • 두 번째 network Connections은 새로 추가된 새 새 HTTP 트래픽 프로파일러입니다.

  • 녹화를 시작하면 데이터가 캡처되며, 캡처된 데이터에는 전송된 모든 정보가 포함됩니다.
  • 이 기록된 데이터는 민감한 정보를 포함할 수 있기 때문에, 추적 파일의 관리에 주의를 기울여야 합니다.

  • HTTP Traffic 항목을 선택하면 주고받은 전체 데이터가 나타납니다.

  • 이 예제에서는 latest에서 이미지 목록을 받아오는 작업이 처음 실행되는 것을 볼 수 있습니다.

  • 그다음 작업에서는 목록의 모든 이미지 썸네일을 불러오는 것을 볼 수 있습니다.

  • 해당 데이터가 있는 영역을 드래그하면, 해당 범위의 시간이 표시됩니다.
  • 이 예제에서는 약 8.97초가 소요되었음을 알 수 있습니다.

  • 처음 몇 개의 이미지는 상당히 빠르게 처리되었지만, 점점 Blocked 된 상태가 길어지는 것을 볼 수 있습니다.
  • 따라서 동시에 많은 요청을 하는 것이 문제인 것으로 추정할 수 있습니다.
  • 해당 작업 위로 마우스를 가져가면 작업의 전체 수행 시간과 마우스가 있는 상태의 기간이 표시됩니다.
  • 이 예제에서는 작업의 대부분의 시간이 Blocked 상태에서 소요되었음을 알 수 있습니다.

  • 차단된 이유를 확인하기 위해서 HTTP Transactions by Connection 항목으로 전환할 수 있습니다.

  • 이 화면에서는 트랜잭션이 연결 별로 그룹화됩니다.
  • 여기서는 총 6개의 연결이 있음을 알 수 있습니다.

  • 각 연결에서 트랜젝션이 순차적으로 Blocked 상태로 이전 트랜젝션을 기다리고 있음을 볼 수 있습니다.

  • 각 트랜잭션은 한 연결의 이전 트랜잭션이 완료될 때까지 대기합니다.
  • 이것을 "Head of Line Blocking"이라고 하며 HTTP/1의 문제점 중 하나입니다.

  • HTTP/2에서는 동일한 서버에 대한 여러 요청을 단일 연결에서 다중화하여 보낼 수 있습니다.
    따라서 HTTP/2에서는 첫 번째 요청이 응답을 기다리는 동안 두 번째 요청을 보낼 수 있습니다.
  • 이를 위해서 앱에서는 아무것도 수정할 필요가 없습니다.
  • 모든 Apple 플랫폼은 HTTP/2를 지원하며 iOS 15 및 macOS Monterey부터 HTTP/3도 지원됩니다.

  • HTTP/2에 대한 서버 지원을 켠 후의 프로파일 결과를 보면 이전처럼 오랜 시간 동안 차단되지 않는 것을 볼 수 있습니다.

  • HTTP Transactions by Connection에서 보면 연결이 이제 하나만 사용되는 것을 알 수 있습니다.
  • 트랜젝션들이 더 이상 Blocked상태에서 많은 시간을 보내지 않고 모든 요청이 동시에 처리되는 것을 볼 수 있습니다.

 

HTTP Cookie 문제 분석 예제

  • 다음 예에서는 한번 로그인한 상태가 다음 요청에서 유지되지 않고, 로그인 화면을 또다시 표시하는 문제에 대해 확인해 보겠습니다.

  • 이 과정을 프로파일 하여 분석하면 401 상태 코드를 두 번 받아서 주황색으로 표시되며, 이를 통해 두 번의 로그인이 필요했다는 것을 볼 수 있습니다.

  • 첫 번째 로그인 과정에서는 로그인한 적이 없기 때문에 예상대로 401 코드를 받습니다.
  • 사용자 이름과 암호를 입력한 다음 요청을 전송했기 때문에 큰 빈 영역이 있습니다.
  • 그다음 요청의 상태 코드는 201로 성공적으로 처리되었음을 나타냅니다.

  • 두 번째의 요청은 이미 로그인을 했으므로 성공적으로 처리되기를 기대하지만, 실제로는 401 응답을 받아 실패하였습니다.
  • 로그인된 사용자인지 유무를 판별하기 위하여 서버는 쿠키 정보를 사용하기 때문에, 이 작업이 쿠키를 보낼 것으로 예상할 수 있습니다.
  • 만일 쿠키를 보낸 경우에는 HTTP 메서드 옆에 쿠키 아이콘이 있어야 하지만 지금은 없는 것을 볼 수 있습니다.

  • 쿠키 아이콘을 통해 첫 번째 로그인 요청에서 응답 부분에 쿠키 정보를 받은 것을 볼 수 있습니다.

  • 원하는 트랜잭션을 선택하면 주고받은 요청의 상세 정보를 볼 수 있습니다.
  • Set-Cookie 헤더를 보면 서버가 설정한 쿠키 정보를 볼 수 있으며, 만료 날짜가 과거 시간으로 되어 잘못된 것을 볼 수 있습니다.

  • 그다음 예제에서는 원하는 이미지를 선택하여 즐겨찾기를 하는 예제입니다.

  • 하지만 즐겨찾기 한 이미지가 목록에 나타나지 않는 문제가 있을 때 문제의 원인을 찾는 과정의 예시를 보겠습니다.

  • 우선 프로파일 결과에서 즐겨찾기를 한 목록을 받아오는 요청에 대해 찾기 위해서 Favorite을 검색창에 입력합니다.

  • 보이는 여러 개의 요청 중에서 즐겨찾기를 수행한 다음의 요청을 선택하면 해당 요청으로 이동합니다.
  • 이 요청은 아주 짧은 시간에 이루어진 것으로 표시됩니다.

  • 실제 서버에서 요청을 처리하기에는 너무 짧은 시간이기 때문에 HTTP Transactions by Connection 화면에서 자세한 정보를 확인할 수 있습니다.

  • 그렇다면 이 요청이 로컬 캐시에서 실행되었다는 것을 알 수 있습니다.
  • 그렇기 때문에 서버의 응답을 기다리는 "Waiting for Response" 상태가 없는 것을 알 수 있습니다.

  • 문제를 해결하기 위해서 캐시를 하지 않도록 서버를 수정하는 방법도 있지만, 앱에서 캐시를 하지 않도록 요청하는 방법도 있을 것입니다.
  • 코드를 수정하려면 요청의 call stack에서 해당 호출을 수행하는 함수를 클릭하여 해당 코드로 이동할 수 있습니다.

  • 그다음 캐시 정책을 reloadRevalidatingCacheData로 설정하여 로컬 캐시를 무시하도록 설정할 수 있습니다.

 

외부 SDK의 의심스러운 동작 분석 예제

  • 그다음 예제에서는 외부의 SDK를 통해서 로그인 버튼을 추가한 다음 이 로그인 버튼의 동작을 측정해 보겠습니다.

  • 이전과 마찬가지로 네트워크 프로파일을 수행하면 요청들이 기록되는 것을 볼 수 있습니다.
  • 이 예제에서는 버튼을 눌렀을 때 요청이 되는 것을 기대했지만, 실제로는 그 이전에 요청이 존재하는 것을 확인하였습니다.

  • 새로 추가된 라이브러리에서 진행하는 요청을 보면 CoreLocation의 이벤트를 받아 위치정보를 전송하는 것을 볼 수 있습니다.

  • 전송된 정보를 보면, 위치 정보를 전송하고 있으며 이는 우리가 SDK에서 기대하지 않은 잘못된 정보수집임을 알 수 있습니다.

  • 이러한 경우 File - Save 명령을 통해 이 기록 내용을 저장하고 공유할 수 있습니다.

  • 저장된 파일에 대해서 xctrace export --input PrivacyViolation.trace --har 명령을 통해 컴퓨터에 Instruments가 설치되어 있지 않더라도 산업 표준 형식인 HAR을 지원하는 모든 도구에서 해당 정보를 확인할 수 있습니다.

 

Next steps

  • 이제 네트워크 프로파일 도구를 사용하여 자신의 앱을 분석할 수 있습니다.
  • URLSession과 URLSessionTask에 적절한 이름을 붙여 디버깅을 쉽게 할 수 있습니다.
  • 항상 최신의 네트워킹 프로토콜을 적용하여 성능 향상을 얻을 수 있습니다.

 

목차: https://nyancoder.tistory.com/2

Comments