Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

RustadvanceddevopsAI generated

Custom Reverse Proxy and Load Balancer

Build a reverse proxy and load balancer in Rust with Tokio and hyper, a small version of what nginx or HAProxy do. It receives HTTP requests and forwards each one to one of several backend servers in turn (round robin), checks the backends' health in the background and stops sending traffic to broken ones until they recover, retries safe requests on another backend when one fails, and records how many requests and how much time each backend handles. You'll learn async Rust with Tokio, the hyper HTTP library, sharing state safely between tasks with Arc and atomics, background tasks, timeouts, correct proxy headers, and testing networked code.

Estimate
~12.5h
Steps
6
Completed by
0
Proposed by
codeseed.app

Tokio · hyper

Project roadmap

  1. 01

    Forward requests to one backend

    ~2.5h

    Create a project with tokio, hyper, hyper-util and http-body-util. Write a server that accepts requests and forwards them to one backend with a hyper client, streaming the body both ways, and returns the backend's response. Remove hop-by-hop headers (such as Connection) and add X-Forwarded-For and X-Forwarded-Proto. Write three tiny test backends that return their own name. Done when: requests through the proxy reach the backend and return its response.

  2. 02

    Balance across a pool

    ~2h

    Read the listen address and backend list from a TOML config file (with serde). Pick the next backend for each request with round robin, using an AtomicUsize counter shared through Arc, so no lock is needed. Return 502 when a backend can't be reached, and 504 when it doesn't answer within a timeout. Done when: repeated requests are spread evenly across the three backends.

  3. 03

    Check backend health

    ~2h

    Spawn a background Tokio task that calls each backend's health path every few seconds with a short timeout. Mark a backend unhealthy after 2 failures in a row and healthy again after 2 successes, storing the state in an AtomicBool per backend. Log every change. Done when: stopping a backend marks it unhealthy within a few seconds, and restarting it brings it back.

  4. 04

    Skip unhealthy backends and retry

    ~2h

    Make the selection skip unhealthy backends, and return 503 when none are healthy. When a request fails to connect, retry it once on another backend, but only for methods that are safe to repeat (GET, HEAD and OPTIONS), never for POST. Done when: with one backend stopped, all requests still succeed, and POST requests are never sent twice.

  5. 05

    Record metrics

    ~1.5h

    Count requests, errors and total response time per backend with atomics, and log each request with the method, path, chosen backend, status and duration. Expose the numbers as JSON on a separate admin port (for example /stats). Done when: /stats shows accurate counts and average times per backend.

  6. 06

    Shut down cleanly and test

    ~2.5h

    On Ctrl+C, stop accepting new connections and let in-flight requests finish (with tokio::signal and a graceful shutdown). Write integration tests that start test backends on random ports: even distribution, skipping a stopped backend, no retry for POST, timeouts returning 504, and all backends down returning 503. Load test on your own machine with a tool like oha or wrk. Done when: cargo test passes, and README.md shows the load test results.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~12.5h · 6 steps

Tech stack

Tokiohyper