3P by GN⁺ | ★ favorite | 댓글 1개
  • NetworkManager가 잠깐의 연결 불안정을 “네트워크 없음”으로 판단하듯, 일부 소프트웨어는 TCP 복구보다 자기 상태 판단을 더 신뢰하지만 실제 네트워크에서는 위험할 수 있음
  • “보낸 데이터는 도착한다”, “양쪽은 결국 전달된 바이트에 합의한다”, “HTTP나 SMTP 같은 애플리케이션 프로토콜로 보장할 수 있다”는 믿음은 일부 상황에서 깨짐
  • ACK 처리 중 연결이 끊기면 송신자는 세그먼트 수신 여부를 알 수 없고, 이 한계는 Two Generals’ Problem처럼 단일 2자 TCP 스트림만으로 해결되지 않음
  • SMTP도 RFC 1047과 RFC 2821에서 이 문제를 다루며, 전달 책임이 넘어가는 순간에는 연결 실패 시 중복 전송이나 누락이 생길 수 있는 애매한 구간이 있음
  • 이상한 네트워크를 예외로 치거나 Nagle 알고리듬, 혼잡 제어, ICMP 차단 같은 세부 동작을 무시하면 실제 장애를 잘못 해석하기 쉬움

TCP보다 먼저 네트워크 상태를 단정하는 문제

  • NetworkManager를 쓰던 사용자는 과거 기숙사와 캠퍼스 로밍 환경에서 무선 연결 불안정을 겪었고, 패킷 손실이 조금만 있어도 시스템 전체에 “네트워크 없음”이 전달되는 상황을 경험함
  • 당시 네트워크는 곧 돌아올 가능성이 있었고, 일반적인 TCP 복구가 지연 시간 급증을 동반하더라도 애플리케이션에는 투명하게 보일 수 있었음
  • 이 사례는 TCP가 처리할 수 있는 일시적 장애를 애플리케이션이나 시스템 컴포넌트가 너무 빨리 실패로 해석하는 문제와 이어짐

TCP에 대해 흔히 틀리는 믿음

  • 다음 문장들은 TCP를 다룰 때 자주 나오는 믿음이지만, 각각 적어도 어떤 경우에는 거짓
    • TCP는 신뢰 가능하므로 보낸 모든 데이터가 상대에게 도착함
    • TCP는 대체로 신뢰 가능함
    • TCP가 완전한 의미의 신뢰성을 제공하지 않더라도, 송신자와 수신자는 결국 어떤 바이트가 전송됐는지 정확히 합의함
    • HTTP나 SMTP 같은 메시지 지향 애플리케이션 프로토콜을 TCP 위에 만들면 그런 보장을 만들 수 있음
    • TCP 패킷이라는 것이 있음
    • TCP 패킷이라는 것은 없음
    • 잘 알려진 원격 호스트에 연결하지 못하면 오프라인임
    • Nagle 알고리듬은 좋음
    • Nagle 알고리듬은 나쁨
    • Nagle 알고리듬을 신경 쓸 필요가 없음
    • TCP는 네트워크를 지나는 양방향 Unix pipe처럼 생각해도 충분함
    • 네트워크가 TCP에 투명하면 IP에도 투명함
    • 네트워크가 HTTP/1.1에 투명하면 TCP에도 투명함
    • 표준 프로토콜에 투명하지 않은 이상한 네트워크는 예외적이라 무시해도 됨
    • TCP는 IP 위에 구현됨

전달된 바이트를 정확히 합의하기 어려운 이유

  • TCP 신뢰성과 관련된 앞의 1~4번 문제는 Two Generals’ Problem과 연결됨
  • ACK가 아직 처리 중인 상태에서 연결이 끊기면, 송신자는 해당 세그먼트가 수신됐는지 확인할 방법이 없음
  • 이 한계는 TCP 위에 복잡한 계층을 더 쌓아도 사라지지 않음
  • 단일 2자 TCP 스트림 위에서는 이 보장을 만들 수 없고, 그런 보장에는 PaxosRaft와 유사한 방식 및 최소 3개 노드가 필요함
  • 같은 종류의 문제는 TCP뿐 아니라 UDP나 IP 기반의 2자 서비스에도 적용됨

SMTP가 드러내는 전달 책임의 회색 지대

  • SMTP는 양쪽이 메시지 수신 여부를 명시적으로 신경 써야 하는 서비스라 이 문제가 잘 드러남
  • RFC 1047은 SMTP 관점에서 이 문제를 다루고, RFC 2821은 구현이 RFC 1047의 핵심 조언을 따라야 한다고 정함
  • SMTP 예시에서는 다음 상태들이 구분됨
    • 클라이언트에서 서버로 이메일이 전송됐다고 양쪽이 합의하는 지점에 도달할 수 있음
    • 서버가 이메일 전달 책임을 맡았다고 양쪽이 합의하는 지점에도 도달할 수 있음
    • 하지만 그 전에 누가 현재 이메일 전달 책임을 지는지 애매한 상태를 반드시 지나야 함
  • 이 애매한 상태에서 연결이 끊기면 이메일을 중복하거나 누락하게 됨
  • SMTP 명세는 이메일을 중복하는 쪽을 지정하지만, 실제 구현에서 어느 정도 테스트됐는지는 알 수 없음
  • Paxos와 Raft의 목적은 최종 상태 자체를 달성하는 것보다, 이런 애매한 상태를 방지하는 데 있음

2자 합의에서 남는 지식의 한계

  • 한 댓글은 불신뢰하지만 악의적이지 않은 링크에서도 두 당사자가 일부 바이트 집합에 대해 “전달됐고 양쪽 모두 그 사실을 안다”고 합의할 수 있다고 봄
  • 보충 논의에서는 한 당사자가 합의 집합에 최소한 처음 N바이트가 포함된다는 사실은 알 수 있지만, 합의 집합이 정확히 처음 N바이트라고 알 수는 없다고 정리함
  • 따라서 “확실히 전달됐고 양쪽이 안다”는 바이트 집합은 존재할 수 있어도, 그 뒤에는 송신자와 수신자가 서로의 지식 상태를 확정할 수 없는 회색 지대가 남음
  • 이 차이를 놓치면 분산 시스템에서 이상한 실패가 발생하기 쉬움

현실 네트워크와 하위 계층의 함정

  • “표준 프로토콜에 투명하지 않은 이상한 네트워크는 무시해도 된다”는 믿음은 여러 번 문제를 일으킴
  • buffer bloat는 라우터가 혼잡 제어 메커니즘을 깨뜨리는 사례로 다뤄짐
  • ICMP를 차단하거나 이해하지 못하는 트래픽을 떨어뜨리는 네트워크도 문제가 될 수 있음
  • “혼잡 제어를 알 필요가 없다”는 믿음 역시 TCP를 잘못 이해한 사례에 가까움
    • 하위 예로 “원하는 속도가 나오지 않으면 TCP 연결을 여러 개 열면 된다”는 생각이 나옴

댓글과 토론

Hacker News 의견들
  • 프로그래머가 믿는 거짓들” 형식처럼 일부러 명확히 설명하지 않은 단정들을 던지는 방식은 별로 도움이 안 되고 불쾌하게 느껴짐

    • 저수준 네트워킹 소프트웨어를 직업으로 다루지만, 이 글은 대체로 의미 없는 장광설에 가깝고 과시욕에서 나온 듯함
      “화면은 어떻게 검은색을 보여주나?”라고 묻고는 모든 답에 “아님”이라고 하는 엔지니어 같음. 생각하게 만드는 방식일 수는 있지만, 부정성과 과시가 강해서 많은 수신자에게는 결국 거부감을 주고, 어떤 사람은 이런 식으로 남을 몰아붙이게 되거나 아예 분야에서 멀어질 수 있음. 모두에게 더 잘 먹히고 더 빠르게 가르치며 정확도와 기억 유지도 높이는 교육 방식이 훨씬 많음
    • 맥락과 의도한 독자를 충분히 고려하지 않는 듯함. 이건 누군가의 글에 답글로 올라온 가벼운 포럼 메시지
      완성된 “프로그래머가 믿는 거짓들” 글을 쓴 게 아니라, 그런 글이 있으면 좋겠다고 제안하면서 다룰 만한 출발점을 던진 것에 가까움. “시동을 걸기 위해” 목록을 냈다고 했으니 완성품으로 보지 않는다는 뜻이고, HN 첫 화면에서 우연히 보는 모두가 아니라 같은 포럼의, 이 주제에 더 익숙할 법한 독자들에게 보낸 글임
    • 이 형식의 출발점은 https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-...라고 봄. 중요한 차이는 원래 글의 각 항목은 그 자체로 설명 가능했는데, 이후 많은 “Falsehood…” 목록 작성자들이 그 점을 놓친다는 것임
    • 이런 목록이 프로그래머들이 실제로 믿는 내용을 담고, 왜 틀렸는지 설명했다면 꽤 유용했을 것임. 모호한 문장이 “거짓”이고 그 반대도 “거짓”이라는 식의 근거 없는 단정은 이해하기 어렵다
    • 동의함. 이건 그런 목록 중에서도 잘 만든 편이 아니고, “내가 TCP 지식이 많다는 걸 보여주기 위한 의심스러운 꼬투리 잡기”에 가까움
      1~4번은 두 장군 문제를 알고 있고, 이 맥락에서 “신뢰 가능”이 무슨 뜻인지도 알고 있음. 5~6번은 그냥 이상함. 7번은 명백히 사실이 아니고 아무도 그렇게 생각하지 않음. 8~9번은 Nagle 알고리즘의 이유와 결함이 잘 알려져 있음. 10번은 심지어 맞지도 않고, 대부분의 경우 신경 쓸 필요가 없음. 추상화의 목적이 바로 그거고, 광범위한 성능 최적화를 할 때나 신경 쓰면 됨. 11번도 틀렸고 TCP를 양방향 파이프로 생각해도 됨. 역시 추상화의 목적임. 12번은 정확히 뭘 말하려는지 모르겠지만 TCP와 UDP가 인터넷에서 사실상 동작할 가능성이 있는 거의 유일한 프로토콜이라는 점은 잘 알려져 있음. 13번도 마찬가지로 DoH 같은 많은 프로토콜이 왜 “HTTPS 위에서” 돌아가는지 다들 앎. 14번은 기술적 논점이 아님. 15번은 뭘 말하는지 모르겠지만 “바이트는 8비트다”류라면 현대 세계에서는 실제로 맞는 말임
  • “다음 문장들은 모두 적어도 가끔은 거짓이지만, 일부는 자주 그렇지는 않을 수 있다”면서 5번 “TCP 패킷이라는 것이 있다”와 6번 “TCP 패킷이라는 것은 없다”를 같이 놓은 부분을 전혀 이해 못 하겠음
    TCP 패킷이라는 개념이 있거나 없거나 둘 중 하나 아닌가. 어떤 시나리오에서 쓰이지 않는다고 해도 “그런 건 없다”가 때때로 맞는다고 말할 수 있는지 모르겠음. 내가 의도를 오해한 것일 수도 있지만, 다른 “프로그래머가 믿는 거짓들” 글에서 이런 철학적 혼란을 느낀 적은 없음

    • 엄밀히 말하면 TCP에는 세그먼트, IP에는 패킷, Ethernet에는 프레임이 있음. 단순한 경우에는 1:1로 대응하지만 항상 그렇지는 않음
      https://networkengineering.stackexchange.com/questions/50083...
      특히 중간 라우터의 단편화 때문에 서버와 수신자가 프레임·패킷 경계에 대해 다르게 볼 수 있음. TCP는 어떤 일이 벌어지든 “신뢰 가능한” 파이프 같은 서비스를 만들어야 하고, 애플리케이션 계층은 그 과정이 보이지 않아야 함
    • 이 항목은 놀라운 진실을 알려준다기보다, 목록 작성자가 나와 소통에 실패하는 느낌임
      “TCP 세그먼트가 항상 IP 패킷과 1:1로 들어맞지는 않는다, 하지만 현실에서는 대체로 그렇다”는 뜻인지, “TCP에는 패킷이 아니라 세그먼트가 있다, 하지만 TCP 패킷이라고 해도 다들 알아듣는다”는 뜻인지, 아니면 전혀 다른 뜻인지 알 수 없음
    • 실제 의미는 패킷에는 충분히 인접한 노드 사이에서 잘 정의된 경계가 있지만, 임의의 중간 장비를 지나며 종단 간 경계가 유지된다는 보장은 없다는 것임
    • TCP 데이터 스트림이 IP 패킷으로 나뉘는 방식을 말하는 듯함. IP 관점에서는 패킷이 있고, 애플리케이션 관점에서는 데이터 스트림이 있지만, 실제로는 더 복잡함
      애플리케이션은 대략 각 write() 끝에서 TCP의 PSH 플래그가 설정되는 시점에 어느 정도 영향을 줄 수 있고, 이는 세그먼트화에도 영향을 줌. 작은 푸시 쓰기는 작은 패킷을 만들기 때문임. 하지만 송신자가 곧바로 보낼 수 없으면 버퍼된 데이터는 write() 경계를 보존하지 않고 큰 패킷으로 전송됨
    • 원래 하나의 패킷이 단편화되면 TCP 헤더가 모든 조각에 들어있지 않을 가능성이 큼. Wireshark에서 TCP 플래그로 필터링하면 된다고 생각한다면, 세상의 90%도 그렇게 느끼긴 함
      DNS를 많이 다루는데, 데이터그램 지향 프로토콜을 스트림 지향 매체로 옮기면서 “효율성” 때문에 한 스트림 안에서 여러 요청을 처리하려면, 그 안에 들어간 데이터그램을 구분할 방법이 필요함. “HTTP처럼 Content-Length: 헤더를 쓰자, 바로 그거야!”라고 생각했을 것 같음
      그러고 나면 90%의 사람들이 TCP 스트림에서 DNS 요청을 처리하려고 할 때 “요청 앞의 이 2바이트는 뭐지? 모르겠지만 그냥 건너뛰자”가 됨. 충분히 동작하긴 할 것임. 어차피 단편화가 있으면 요청 꼬리를 “손상”으로 보고 버릴 테고, 한 패킷에 여러 요청을 보내는 사람이 어디 있겠냐는 식임
      농담처럼 들릴 수 있지만, 여기 꽤 영리한 eBPF 코드가 있음: https://gist.github.com/oghie/b4e3accf1f87afcb939f884723e2b4...
      이 주제를 더 보려면: http://consulting.m3047.net/dubai-letters/dnstap-vs-pcap.htm...
  • 약혼자의 Ethernet 케이블을 뽑아 장애물 주변으로 옮긴 뒤 다시 꽂아도 모든 연결이 살아있는 걸 보고 정말 놀라워했던 기억이 있음. 폭탄이 떨어져도 버티도록 설계된 셈임

    • 요즘은 운영체제 설정에 따라 다름. 많은 운영체제가 친절하게 링크 다운을 감지하고 모든 연결을 재설정하려고 함. 그냥 케이블만 옮기고 싶을 때는 꽤 번거롭다
    • Linux에서는 그렇지만, Windows에서 그렇게 하면 MAC이 링크 펄스 손실을 감지해 인터페이스 다운으로 보고하고, Windows가 “친절하게” 모든 TCP 연결을 재설정함
    • 그 경우에는 대략 이렇게 될 것 같음: 원격 쪽은 뽑힌 연결로 계속 데이터를 보내고, 케이블을 다시 꽂으면 내 컴퓨터의 TCP가 원격에서 새 시퀀스를 받을 때마다 각 연결에서 마지막으로 받은 시퀀스 번호를 ACK함. 원격은 같은 시퀀스 번호에 대한 중복 ACK를 보고 패킷 손실로 해석해 다시 전송할 것임
  • 관련해서, 전달 보장은 최대 한 번 또는 최소 한 번까지만 가능하고, 정확히 한 번 전달은 불가능함. 정확히 한 번 전달 보장이 없다는 걸 버그로 여기는 주니어를 볼 때마다 1달러씩 받았다면 꽤 모였을 것임

    • 최소 한 번 전달이 가능하다면, 그 위에 정확히 한 번 전달을 왜 만들 수 없는지 궁금함
      더 명확히 말하면, 최소 한 번 전달이 가능할 때 수신 노드 위에 정확히 한 번 전달처럼 보이는 추상화 계층을 만들 수 없는 이유가 뭔가. 받은 메시지 로그를 유지하고 중복을 버리면 간단해 보임
    • 재미있는 사실로, 네트워크에서 실제로 정확히 한 번 전달을 얻을 수는 있음. 다만 그 네트워크가 Ethernet/IP/TCP가 아니어야 함
      이 계층들은 모두 메시지의 정확히 한 번 전달을 가능하게 하기에는 잘못 설계돼 있음. TCP는 애초에 메시지라는 개념조차 없음. 그 네트워크 내부에서도 “정확히 한 번” 메시지 전송이 일어나는 건 아니고, 특정 작은 패킷에 대해서는 내부적으로 “최소 한 번”이겠지만, 네트워크 프로토콜은 소프트웨어에 정확히 한 번 전달을 제공하도록 설계될 수 있음
      HPC 밖에서 대부분 그렇게 하지 않는 진짜 이유는, 네트워크 계층의 정확히 한 번 전달이 웹 쪽 대부분에는 그다지 유용하지 않기 때문임. 어차피 상위 계층이 무언가를 버리고 재시도할 테니, 문제를 스택 위로 올려버리는 편이 낫다
    • 붐비는 방에서 누군가에게 소리쳐 메시지를 전달하는 예로 설명하려고 함. 상사에게 “버그 고쳤습니다”라고 외치면 상사는 확인해 줄 수도, 무시할 수도 있음. 메시지를 반복하지 않으면 최대 한 번 전달
      확인을 받을 때까지 같은 메시지를 반복하면 최소 한 번 전달임. 핵심은 메시지를 받았다는 확인에 있음. 확인을 받지 못했다면, 그 메시지는 최대 한 번 전달된 상태임
    • 이건 널리 퍼진 말이지만 기본적으로 틀렸다고 봄
      임의로 나쁜 네트워크 분할에 대해서는 보장이 매우 제한적이지만, 이런 상태는 감지 가능한 조건이기도 함. 결함 있는 시스템은 많지만, 일반적으로 제대로 만든 시스템은 정확히 한 번 전달 또는 감지된 실패를 보장함
  • 작성자는 오류 정정 코드를 들어본 적이 없는 건가 싶음. 손실 가능성을 가정하고, 변조되거나 빠진 바이트를 정정하거나 최소한 감지하기 위해 바이트를 추가하는 게 그 목적임. 그래서 TCP, 아니면 Ethernet 프레임에 FEC 바이트가 메시지 형식으로 들어가는 것 아닌가 싶음
    또한 TLS 위의 HTTP에는 암호화된 데이터 프레임이 있고, 이런 상황이 자주 일어난다면 많은 경우 수신 불가능했을 것임. 현대 인터넷 상당 부분이 이 패러다임 위에 있다는 점을 생각하면, 이 항목들 다수는 드물고 지나치게 꼬투리 잡기에 가까워 보임
    글이 암시하지만 설명하지 않은 미묘한 부분에는 대체로 동의하는 입장에서도 이렇게 느껴짐. 훌륭한 기술 글은 상호 발견과 더 깊은 이해를 염두에 두고 쓰이며, 실제 설명을 남기지 않으면 둘 다 달성하기 어렵다

    • TCP도 Ethernet도 순방향 오류 정정을 제공하지 않음. Ethernet 프레임에는 32비트 CRC가 들어가고, TCP 세그먼트는 이른바 “인터넷 체크섬”을 사용함
    • 글의 어느 부분이 오류 정정 코드나 데이터 체크섬과 관련 있다고 보는지 모르겠음. 처음 네 항목은 전송 매체가 바이트를 바꾸지 않고 특정 시점에 그냥 사용할 수 없게 되는 경우에도 참임
  • “ACK가 남아 있는 동안 연결이 끊기면, 송신자는 세그먼트가 수신됐는지 알 방법이 없다”는 대목에서 진짜 질문은 왜 이걸 TCP가 풀어야 하는 문제로 봐야 하느냐는 것임
    TCP는 양방향 물줄기 같은 파이프를 제공하고, 그 정도면 많은 유용한 애플리케이션을 만들기에 충분함. TCP는 올바른 전달 보장을 제공한 적이 없고, 그건 애플리케이션의 몫임
    예를 들어 HTTP 요청이 응답을 받기 전에 중단되면, 송신자는 요청이 서버에 도달하지 않았다고 가정하고 새 연결로 다시 시도해야 함. 서버는 중복 요청을 완화해야 하고, 거부하거나 성공 코드를 반환해야 함
    어쩌면 이게 글의 요점일 수도 있음. 중복 요청을 보내면 많은 웹 페이지가 혼란스러워하니까

    • 서버가 요청을 봤을 수도 있고 아닐 수도 있으며, https://en.wikipedia.org/wiki/Two_Generals%27_Problem는 모든 경우에 이를 아는 것이 불가능하다는 점을 증명함. ACK를 아무리 많이 주고받아도 마지막 ACK가 유실될 수 있음
      상태를 바꾸는 요청은 같은 멱등성 키로 재시도해야 하고, 서버는 요청된 작업이 이미 일어났는지 여부를 ACK하려고 해야 함
  • 좀 과감히 말하면, 자기 하드웨어로 운영하는 데이터센터 내부에서는 저수준 꼬투리나 “이상한 네트워크”를 대체로 무시하고 TCP를 양방향 Unix 파이프처럼 써도 안전함
    “대체로”라는 단서는 있음. 당연히 대역폭 한계, 초당 패킷 수 한계, 지연 시간은 여전히 신경 써야 함

    • 데이터센터 네트워크를 아주 탄탄히 이해하고 있고 100% 항상 정상이라는 확신이 없다면 그렇게 하지 않겠음. 서버 쪽에서 일해본 경험상 그럴 가능성은 낮음
      스위치 두 대 사이의 광학 장비가 더러워지면 패킷 손실이 생기고 TCP가 본색을 드러냄. 지금은 문제가 아닐 수 있겠지만, 마이크로버스트를 진단하는 일은 아주 재미있었고 TCP를 정말 혼란스럽게 만듦. “패브릭 혼잡”도 겪어봤음. 진짜 골치 아픈 건 서버에는 2배 집계, 랙 상단 스위치에서 스파인 스위치로는 4배 집계가 있어서 인접 랙의 두 서버 사이에 각 방향으로 8개 경로가 있는데, 그중 하나만, 때로는 한 방향만 99.9%로 동작하는 경우임. 스위칭 지표에 대한 가시성이 없으면 추적하기 정말 힘듦
      [1] https://en.m.wikipedia.org/wiki/Micro-bursting_(networking)
  • 여기 비판하는 사람들 중 일부는 “누군가 그런 글을 써야 한다 […] 자, 내가 시동을 걸어보겠다”라는 프레이밍을 봤는지 모르겠음. 이건 다듬어진 글이라고 주장하는 게 아님. 그래서 HN 제출 제목도 오해를 부른다고까지 말할 수 있음

  • VKontakte에서 일할 때 해결하려 했던 아주 구체적인 문제가 떠오름. 인스턴트 메시징과 불안정한 모바일 데이터 연결에 관한 문제였음
    지하철역을 떠나는 열차 안에서 메시지를 보냈다고 해보자. 요청은 서버에 도달하지만, 응답이 돌아올 때쯤에는 열차가 터널 안에 들어가 신호가 끊김. 클라이언트는 메시지 전송에 실패했다고 생각하지만 실제로는 성공적으로 전송된 상태임. 클라이언트는 다시 온라인이 되면 재시도하고, 같은 메시지를 한 번 더 보냄
    해결책은 각 요청마다 클라이언트가 생성한 “무작위 ID”를 보내는 것이었음. 훨씬 나중에 이것이 관례적으로 멱등성 토큰이라고 불린다는 걸 알게 됨. 이 방식은 동작했지만 또 다른 문제가 생김. 메시지를 보낸 요청의 응답보다, 긴 폴링으로 자기 메시지를 먼저 받는 경우가 있음. 그 메시지가 방금 보낸 것인지, 같은 계정의 다른 클라이언트가 보낸 다른 메시지인지 확실히 알 수 없음. 아직 내 메시지의 ID를 모르기 때문임. 그래서 클라이언트 쪽에서 미완료 발신 메시지가 모두 완전히 전송되고 ID가 알려질 때까지 발신 메시지 처리를 지연시켜 해결했음
    Telegram은 훨씬 더 우아하게 해결했음. 클라이언트가 서버에 재연결하면, 서버가 이전 연결에서 ACK되지 않은 모든 응답을 보내줌. MTProto는 TCP와 별개로 자체 ACK 메커니즘을 갖고 있음
    그래서 인스턴트 메시징은 처음엔 사소해 보이지만, TCP가 충분히 새는 추상화라서 애플리케이션 계층에서 그 누수를 막아야 한다는 걸 알게 됨

    • 파일 동기화 앱에서 두 번째 문제를 다뤄야 했음. 해결책은 요청과 폴링/푸시에 device id를 전파해서, 원래 변경을 만든 기기가 자신이 만든 변경을 무시할 수 있게 하는 것이었음
    • 솔직한 질문인데, 메시지의 멱등성 토큰을 클라이언트에 다시 보내면 안 됐던 이유가 궁금함. 그러면 익숙한 로컬 데이터베이스 잠금 문제처럼 다룰 수 있을 것 같음
    • 클라이언트가 무작위로 생성했다면 그 ID를 알고 있는 것 아닌가 싶음
    • 분산 시스템에서는 거의 아무것도 사소하지 않다는 걸 배웠음
  • 아직도 많은 사람이 TCP가 함수 호출이 아니라는 점이나 느린 시작, 혼잡 회피 같은 동작을 이해하지 못한다는 게 정말 놀라움
    최근에 TCP용 새 속도 제한기가 지나갔는데 너무 심각하게 망가져 있었고, 세상의 대부분 컨테이너가 전반적으로 버퍼블로트를 겪고 있을 것 같다는 생각을 떨칠 수 없음