4 điểm bởi GN⁺ 2024-01-17 | 1 bình luận | Chia sẻ qua WhatsApp
  • Speedbump là một proxy TCP được viết bằng Go, dùng để mô phỏng tình trạng trễ bằng cách thêm độ trễ mạng biến thiên vào lưu lượng TCP được proxy
  • Có thể cộng thêm các thành phần độ trễ dạng sóng sin, răng cưa, sóng vuông, tam giác lên độ trễ cơ bản, và có thể kết hợp nhiều thành phần độ trễ cùng lúc
  • Ví dụ cho thấy cấu hình proxy lưu lượng hướng tới localhost:80 trên cổng 2000, áp dụng độ trễ cơ bản 100ms, biên độ sóng sin 100ms và chu kỳ 1m
  • Có thể cài đặt bằng cách tải binary dựng sẵn theo từng bản phát hành, chạy go build từ mã nguồn, hoặc chạy container image kffl/speedbump
  • Ngoài CLI, có thể dùng như một thư viện thông qua gói lib của Go, với các tham số như kích thước buffer, kích thước hàng đợi độ trễ, mức log, host lắng nghe và cổng

Proxy để mô phỏng độ trễ TCP

  • Speedbump là một proxy TCP được viết bằng Go và có thể mô phỏng độ trễ mạng biến thiên
  • Đích proxy được chỉ định bằng đối số <destination> của CLI, với định dạng được hướng dẫn là host:post
  • Cách hoạt động cơ bản là proxy lưu lượng TCP tới đích đồng thời thêm độ trễ đã cấu hình

Cài đặt và cách chạy

  • Cách cài đặt dễ nhất là tải binary dựng sẵn được đính kèm tự động trong mục Assets của từng release
  • Nếu muốn build từ mã nguồn, hãy clone kho lưu trữ rồi chạy go build
  • Nếu muốn chạy bằng container, có thể dùng image kffl/speedbump

Ví dụ sử dụng cơ bản

  • Có thể lắng nghe trên cổng 2000 và proxy lưu lượng TCP tới localhost:80, đồng thời áp dụng độ trễ cơ bản 100ms, biên độ sóng sin 100ms và chu kỳ 1m
    • Cấu hình này tạo ra độ trễ bổ sung tối đa 200ms và tối thiểu 0
    • Ví dụ lệnh chạy là speedbump --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
  • Cũng có thể chạy cùng cấu hình đó bằng container image
    • Ví dụ là docker run --net=host kffl/speedbump:latest --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
  • Cũng có thể cấu hình thành phần độ trễ răng cưa
    • Ví dụ là cấu hình với độ trễ cơ bản 300ms, biên độ răng cưa 200ms, chu kỳ 2m, cổng 2000, đích localhost:80
    • Lệnh chạy là speedbump --latency=300ms --saw-amplitude=200ms --saw-period=2m --port=2000 localhost:80

Kết hợp các thành phần độ trễ

  • Speedbump có thể áp dụng đồng thời nhiều thành phần độ trễ
  • README có kèm ví dụ đồ thị độ trễ kết hợp giữa sóng răng cưa và sóng sin

Đối số CLI và sử dụng thư viện

  • speedbump --help cung cấp cách dùng theo dạng speedbump [<flags>] <destination>
  • Các thiết lập mạng chính như sau
    • --host: IP hoặc tên host để lắng nghe; nếu không chỉ định thì sẽ bind vào tất cả giao diện mạng
    • --port: cổng lắng nghe, mặc định là 8000
    • --buffer: kích thước buffer dùng để đọc TCP, mặc định là 64KB
    • --queue-size: kích thước hàng đợi độ trễ dùng để lưu buffer đã đọc, mặc định là 1024
  • Có các giá trị mặc định liên quan đến độ trễ và các tùy chọn dạng sóng
    • --latency: độ trễ cơ bản được thêm vào lưu lượng proxy, mặc định là 5ms
    • --sine-amplitude, --sine-period: biên độ và chu kỳ độ trễ sóng sin
    • --saw-amplitude, --saw-period: biên độ và chu kỳ độ trễ răng cưa
    • --square-amplitude, --square-period: biên độ và chu kỳ độ trễ sóng vuông
    • --triangle-amplitude, --triangle-period: biên độ và chu kỳ độ trễ tam giác
  • Cũng bao gồm các tùy chọn vận hành
    • --log-level: mức log, các giá trị có thể là DEBUG, TRACE, INFO, WARN, ERROR
    • --version: hiển thị phiên bản ứng dụng
  • Speedbump cũng có thể được dùng như một thư viện Go, được cung cấp qua gói lib
  • Giấy phép là Apache 2.0 License

1 bình luận

 
GN⁺ 2024-01-17
Ý kiến trên Hacker News
  • Tôi từng tìm một thứ tương tự để kiểm thử nhiều triển khai ActivityPub ở các quy mô và điều kiện mạng khác nhau, rồi nhận ra trên máy mình đã có sẵn mọi thứ cần thiết qua tc
    Trên bản phân phối của tôi, nó nằm trong gói iproute2, và cũng có mô tả ở đây: https://wiki.archlinux.org/title/advanced_traffic_control
    Để thêm độ trễ cho một interface cụ thể, có thể chạy kiểu như tc qdisc add dev eth0 root netem delay 100ms
    Dễ dùng, hoạt động tốt trong container Docker, có thể áp dụng các điều kiện như độ trễ, mất gói, trùng lặp gói, và nhiều khả năng là đã được cài sẵn

    • tc/netem/tbf thực sự rất hay. Tôi đã làm một GUI Python đơn giản ở phía trên và chạy nó trên một Pi đặt trong vỏ có màn hình cảm ứng; đó là một chiếc hộp đen nhỏ với các tùy chọn như “rớt gói: [0%] [1%] [10%] [50%] / hỏng gói: ...”, và khách hàng khá ấn tượng
      Khá bất ngờ là tôi không thấy frontend tương tự nào dưới dạng sản phẩm phần cứng thương mại; nếu không phải tôi tìm sót thì có vẻ thị trường chưa có
    • Nhược điểm của tc là khi muốn áp dụng cho gói tin nhận vào thì hơi kỳ quặc và rắc rối
      Trước đây tôi từng tự làm một emulator để bắt chước một thiết bị đầu cuối vệ tinh thương mại cụ thể. Thiết bị đó xếp gói vào hàng đợi, rồi khi đạt một ngưỡng nhất định hoặc quá thời hạn thì phóng ra thành một cụm; nó còn “tử tế” sắp xếp lại các gói nhỏ lên phía trước hàng đợi để giảm độ trễ, nhưng TCP stack cực kỳ ghét chuyện đó
    • Điểm hay của speedbump là có thể điều chỉnh điều kiện lỗi theo thời gian. tc không làm được việc đó
      Nó có thể khá hữu ích để mô phỏng ảnh hưởng thời tiết lên vệ tinh/RF thay đổi theo thời gian
  • Netflix từng làm đúng thứ này, tên là latency monkey
    Họ nhận ra việc xác định một dịch vụ phụ có “chậm” hay không khó hơn nhiều so với xác định nó có “không khả dụng” hay không, nên đây là một cách quan trọng để kiểm thử cách dịch vụ xử lý tình trạng chậm và sự cố mạng
    Cách triển khai rất đơn giản: nó thả gói theo một tỷ lệ cấu hình được, khiến việc truyền lại bị ép buộc, và phía bên kia sẽ nhận các gói đến trễ và lộn thứ tự
    Cuối cùng, nó phát hiện được rất nhiều vấn đề trong mã xử lý lỗi liên quan đến truy cập mạng

  • Tôi nghĩ mọi kỹ sư phần mềm xây dựng ứng dụng Internet tương tác đều nên dùng các công cụ như vậy trong công việc hằng ngày. Không chỉ TCP mà cả QUIC cũng cần, và để bắt cả DNS thì lý tưởng là phải bao gồm toàn bộ UDP
    Tôi tin chắc 90% tình trạng webapp phình to sẽ biến mất nếu người làm ra chúng không chỉ dùng những môi trường máy tính “Cadillac mạ vàng”

  • Trong các môi trường có kết nối mạng đứt quãng, chẳng hạn tình huống cứu trợ thảm họa, nhiều ứng dụng hoạt động rất tệ
    Nếu nhiều nhà phát triển ứng dụng hơn mô phỏng và kiểm thử kết nối chập chờn, điều đó có thể giúp ích cho người khác
    Nội dung từ “Toxiproxy is a framework for simulating network conditions” (2021) https://news.ycombinator.com/item?id=29084277#29088775:

    Nhiều ứng dụng không có chức năng ‘giữ trong hộp thư đi’ như ta kỳ vọng ở một email client chẳng hạn

    • [ ] Ai có thể tạo một bộ toxiproxy ‘test case mutator’ tham khảo để mô phỏng các sự cố kết nối #DisasterRelief phổ biến?
    • Điều tôi ghét nhất là khi người ta không lấp đầy buffer trước khi gửi gói. Khi đó, trên một kết nối Internet tệ — tức môi trường có rớt gói và độ trễ cao gây truyền lại TCP — đột nhiên chỉ còn 120kps
      Vì bạn chỉ gửi các gói 50 byte, và cứ 10 gói thì mất 1 gói. Trong lúc đó, một thread trên server không làm được việc hữu ích nào
  • Trên Mac, chỉ dùng công cụ tích hợp sẵn cũng làm được điều tương tự

    # Setup pipe  
    sudo dnctl pipe 1 config bw 1Kbit/s delay 800
    
    # Setup matching pf rule  
    echo "dummynet out proto tcp from any to 127.0.0.1 port 11211 pipe 1" | sudo pfctl -f -
    
    # Turn on firewall  
    sudo pfctl -e
    
    # Test  
    time nc -vz 127.0.0.1 11211  
    Connection to 127.0.0.1 port 11211 [tcp/*] succeeded!  
    nc -vz 127.0.0.1 11211 0.01s user 0.00s system 0% cpu 1.333 total  
    
    • Dummynet và các tính năng này có nguồn gốc từ FreeBSD, và đã có ở đó từ rất lâu. Hơn 15 năm trước tôi đã dùng nó để kiểm thử mất gói, và nó hoạt động tốt
  • Có một dự án đã không hoạt động một thời gian, nhưng chỉ cái tên đã nói lên rất nhiều: https://github.com/tylertreat/comcast

  • Gần đây khi cố mô phỏng mạng chậm trên Mac, tôi tìm thấy Network Link Conditioner, và nó khá ổn. Không cần thiết lập kiểu proxy gì cả
    Cần cài từ các công cụ bổ sung của Xcode
    https://nshipster.com/network-link-conditioner/

  • Công cụ tuyệt vời toxiproxy của Shopify cũng đáng xem: https://github.com/Shopify/toxiproxy
    Đây cũng là một cách rất hay để tự triển khai và kiểm thử thư viện networking, vì stack phải xử lý đúng phần lớn các tình huống bất lợi
    Ý tưởng ‘chaos engineering’ thật tuyệt

    • Ban đầu tôi cũng tìm đến toxiproxy, nhưng mô hình client-server không hợp với tôi, còn speedbump thì vừa khớp với nhu cầu mô phỏng độ trễ HTTP của tôi
      Tôi đang phát triển thanh tiến trình cho web crawler, nhưng khi kiểm thử trên localhost thì quá nhanh nên khó biết có vấn đề gì không
      Với speedbump, chỉ cần chạy podman run --net=host kffl/speedbump:latest --latency=1s --port=8001 localhost:8000 rồi kiểm thử crawler tại http://localhost:8001 là được
      Một công cụ gọn gàng
  • Tôi từng dùng một công cụ tương tự trên Windows
    https://jagt.github.io/clumsy/

    • Khoảng 10 năm trước tôi dùng nó để kiểm thử nhiều điều kiện mạng liên lục địa, và kết quả khá sát thực tế. Đáng khuyến nghị
    • Trông có vẻ hay, nhưng nhìn ảnh chụp màn hình thì có vẻ là áp dụng toàn hệ thống với filter, chứ không phải áp dụng theo từng adapter
  • FreeBSD cũng có dummynet như một phần của ipfw, có thể chèn độ trễ, giới hạn băng thông, kích thước hàng đợi và mất gói. Đây là cùng chức năng với thứ có trên MacOS

    • Có giống tc trên Linux không?