voyager is a web framework written in rust, inspired by Go net/http
- totally based on rust
- clean api learned from Go
- middleware based
- module design, interface first so components are replacable
run the hello example:
cargo run --example hello
curl -i localhost:8080/hello
curl -i localhost:8080/hi
curl -i localhost:8080/static/test.png
http::listen_and_serve
accept aServer
instance and run the serverserver::Server
is a trait that defines how to implement a server that can serve requests, with this abstraction users can implement their own flavor of server, the default server is implemented bytokio
andhttp
crate.mux::DefaultServeMux
contains a default mux implementation to route requests to handler.
Because tokio
works on multiple threads, so every shared data must be wrapped by Arc
.
before commit run:
cargo fmt
cargo clippy
- using radix tree to implement a mux
- implement worker pool to increase performance
- middleware
- json example see
- a database example
- static file serving(./examples/hello.rs)
demo code
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
var persons []Person
persons = append(persons, Person{
ID: 1,
Name: "person1",
Age: 10,
})
persons = append(persons, Person{
ID: 2,
Name: "person2",
Age: 20,
})
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
})
http.HandleFunc("/person", func(w http.ResponseWriter, r *http.Request) {
person := persons[0]
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(person)
})
http.ListenAndServe(":8081", nil)
}
command:
go run main.go
wrk2 -t2 -c100 -d30s -R2000 http://127.0.0.1:8081/person
result:
Running 30s test @ http://127.0.0.1:8081/person
2 threads and 100 connections
Thread calibration: mean lat.: 1.130ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 1.394ms, rate sampling interval: 10ms
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.24ms 542.80us 6.44ms 66.07%
Req/Sec 1.05k 1.07k 4.44k 89.87%
58902 requests in 30.00s, 8.03MB read
Requests/sec: 1963.31
Transfer/sec: 274.17KB
demo code is from the json example, command:
cargo run --example json
wrk2 -t2 -c100 -d30s -R2000 http://127.0.0.1:8080/person
result:
Running 30s test @ http://127.0.0.1:8080/person
2 threads and 100 connections
Thread calibration: mean lat.: 1.974ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 1.569ms, rate sampling interval: 10ms
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.72ms 562.29us 5.89ms 72.95%
Req/Sec 1.06k 1.18k 5.55k 88.95%
58902 requests in 30.00s, 9.04MB read
Requests/sec: 1963.27
Transfer/sec: 308.68KB
from this benchmark we can see that voyager framework is almost as fast as go, but tokio get errors
failed to process connection; error = Os { code: 104, kind: ConnectionReset, message: "Connection reset by peer" }