Skip to content

Instantly share code, notes, and snippets.

@bachue
Last active June 14, 2019 03:35
Show Gist options
  • Select an option

  • Save bachue/82a1f2819d8ccc309f19b57f5a1b19b9 to your computer and use it in GitHub Desktop.

Select an option

Save bachue/82a1f2819d8ccc309f19b57f5a1b19b9 to your computer and use it in GitHub Desktop.

Revisions

  1. bachue revised this gist Jun 14, 2019. No changes.
  2. bachue created this gist Jun 14, 2019.
    354 changes: 354 additions & 0 deletions actix-web_vs_gin.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,354 @@
    # Rust by actix-web 1.0

    ## /ping 结果
    ```
    This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    Benchmarking localhost (be patient)
    Server Software:
    Server Hostname: localhost
    Server Port: 8080
    Document Path: /ping
    Document Length: 4 bytes
    Concurrency Level: 500
    Time taken for tests: 10.786 seconds
    Complete requests: 100000
    Failed requests: 0
    Write errors: 0
    Total transferred: 12000000 bytes
    HTML transferred: 400000 bytes
    Requests per second: 9271.66 [#/sec] (mean)
    Time per request: 53.928 [ms] (mean)
    Time per request: 0.108 [ms] (mean, across all concurrent requests)
    Transfer rate: 1086.52 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 26 7.3 25 64
    Processing: 9 28 7.5 28 65
    Waiting: 1 15 7.2 14 58
    Total: 26 54 5.8 53 89
    Percentage of the requests served within a certain time (ms)
    50% 53
    66% 55
    75% 56
    80% 57
    90% 60
    95% 64
    98% 71
    99% 76
    100% 89 (longest request)
    ```

    ## /ping3 结果

    ```
    This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    Benchmarking localhost (be patient)
    Server Software:
    Server Hostname: localhost
    Server Port: 8080
    Document Path: /ping3
    Document Length: 4 bytes
    Concurrency Level: 500
    Time taken for tests: 13.972 seconds
    Complete requests: 100000
    Failed requests: 0
    Write errors: 0
    Total transferred: 7900000 bytes
    HTML transferred: 400000 bytes
    Requests per second: 7156.99 [#/sec] (mean)
    Time per request: 69.862 [ms] (mean)
    Time per request: 0.140 [ms] (mean, across all concurrent requests)
    Transfer rate: 552.15 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 27 4.8 26 51
    Processing: 4 43 8.5 42 156
    Waiting: 2 33 7.9 32 139
    Total: 6 70 9.6 68 186
    Percentage of the requests served within a certain time (ms)
    50% 68
    66% 72
    75% 74
    80% 76
    90% 81
    95% 86
    98% 91
    99% 96
    100% 186 (longest request)
    ```

    ## 源码

    ### Cargo.toml

    ```toml
    [package]
    name = "actix-web-test"
    version = "0.1.0"
    authors = ["Bachue Zhou <[email protected]>"]
    edition = "2018"

    [dependencies]
    actix-rt = "0.2"
    actix-web = "1.0"
    futures = "0.1.25"
    r2d2 = "0.8.5"
    postgres = "0.15"
    r2d2_postgres = "0.14.0"
    ```

    ### src/main.rs

    ```rust
    use actix_web::{get, middleware, web, App, Error, HttpResponse, HttpServer, Responder};
    use futures::{future::ok, Future};
    use r2d2_postgres::{PostgresConnectionManager, TlsMode};
    use std::{io, time::SystemTime};
    #[get("/ping")]
    fn ping() -> impl Responder {
    format!("pong")
    }

    fn ping2() -> impl Future<Item = HttpResponse, Error = Error> {
    ok(HttpResponse::Ok().body(format!("pong")))
    }

    fn ping3(
    db: web::Data<r2d2::Pool<PostgresConnectionManager>>,
    ) -> impl Future<Item = HttpResponse, Error = Error> {
    web::block(move || {
    let timestamp = SystemTime::now()
    .duration_since(SystemTime::UNIX_EPOCH)
    .unwrap()
    .as_secs() as i64;
    db.get()
    .unwrap()
    .execute("INSERT INTO test(t) VALUES($1)", &[&timestamp])
    })
    .then(|result| match result {
    Ok(_) => Ok(HttpResponse::Ok().body(format!("pong"))),
    Err(err) => Ok(HttpResponse::InternalServerError().body(format!("{}", &err))),
    })
    }

    fn main() -> io::Result<()> {
    let sys = actix_rt::System::new("http-test");

    let manager =
    PostgresConnectionManager::new("postgres://vagrant@localhost/vagrant", TlsMode::None)
    .unwrap();
    let pool = r2d2::Pool::builder().max_size(1000).build(manager).unwrap();

    pool.get()
    .unwrap()
    .execute("DROP TABLE IF EXISTS test", &[])
    .unwrap();
    pool.get()
    .unwrap()
    .execute(
    "CREATE TABLE test (id SERIAL PRIMARY KEY, t BIGINT NOT NULL)",
    &[],
    )
    .unwrap();

    HttpServer::new(move || {
    App::new()
    .data(pool.clone())
    .wrap(middleware::Logger::default())
    .service(ping)
    .route("/ping2", web::get().to_async(ping2))
    .route("/ping3", web::get().to_async(ping3))
    })
    .bind("127.0.0.1:8080")?
    .start();
    sys.run()
    }
    ```

    # Go by gin v1.4.0

    ## /ping 结果

    ```
    This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    Benchmarking localhost (be patient)
    Server Software:
    Server Hostname: localhost
    Server Port: 8080
    Document Path: /ping
    Document Length: 4 bytes
    Concurrency Level: 500
    Time taken for tests: 11.572 seconds
    Complete requests: 100000
    Failed requests: 0
    Write errors: 0
    Total transferred: 12000000 bytes
    HTML transferred: 400000 bytes
    Requests per second: 8641.48 [#/sec] (mean)
    Time per request: 57.860 [ms] (mean)
    Time per request: 0.116 [ms] (mean, across all concurrent requests)
    Transfer rate: 1012.67 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 28 48.6 25 1033
    Processing: 5 30 8.5 29 227
    Waiting: 1 19 8.3 18 223
    Total: 18 58 49.1 55 1075
    Percentage of the requests served within a certain time (ms)
    50% 55
    66% 59
    75% 61
    80% 62
    90% 67
    95% 72
    98% 77
    99% 82
    100% 1075 (longest request)
    ```

    ## /ping3 结果

    ```
    This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    Benchmarking localhost (be patient)
    Server Software:
    Server Hostname: localhost
    Server Port: 8080
    Document Path: /ping3
    Document Length: 4 bytes
    Concurrency Level: 500
    Time taken for tests: 15.398 seconds
    Complete requests: 100000
    Failed requests: 0
    Write errors: 0
    Total transferred: 12000000 bytes
    HTML transferred: 400000 bytes
    Requests per second: 6494.44 [#/sec] (mean)
    Time per request: 76.989 [ms] (mean)
    Time per request: 0.154 [ms] (mean, across all concurrent requests)
    Transfer rate: 761.07 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 26 38.3 25 1039
    Processing: 4 50 38.9 47 1195
    Waiting: 2 40 38.7 36 1190
    Total: 4 76 54.5 72 1217
    Percentage of the requests served within a certain time (ms)
    50% 72
    66% 77
    75% 80
    80% 83
    90% 91
    95% 100
    98% 112
    99% 127
    100% 1217 (longest request)
    ```

    ## 源码

    ### go.mod

    ```
    module gitlab.qiniu.io/zhourong/gin-test
    go 1.12
    require (
    github.com/gin-gonic/gin v1.4.0
    github.com/lib/pq v1.1.1
    github.com/mattn/go-sqlite3 v1.10.0 // indirect
    )
    replace golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 => github.com/golang/crypto v0.0.0-20190308221718-c2843e01d9a2
    replace golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c => github.com/golang/net v0.0.0-20190503192946-f4e77d36d62c
    replace (
    golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a => github.com/golang/sys v0.0.0-20190215142949-d0b11bdaac8a
    golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 => github.com/golang/sys v0.0.0-20190222072716-a9d3bda3a223
    )
    replace golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
    ```

    ### main.go

    ```go
    package main

    import (
    "database/sql"
    "log"
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
    _ "github.com/lib/pq"
    )

    func main() {
    db, err := sql.Open("postgres", "postgres://vagrant@localhost?sslmode=disable")
    if err != nil {
    log.Fatal(err)
    }
    defer db.Close()
    db.SetMaxOpenConns(1000)
    db.SetMaxIdleConns(1000)

    if _, err = db.Exec("DROP TABLE IF EXISTS test"); err != nil {
    panic(err)
    }
    if _, err = db.Exec("CREATE TABLE test (id SERIAL PRIMARY KEY, t BIGINT NOT NULL)"); err != nil {
    panic(err)
    }

    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
    c.String(http.StatusOK, "pong")
    })
    r.GET("/ping3", func(c *gin.Context) {
    if _, err = db.Exec("INSERT INTO test(t) VALUES($1)", time.Now().Unix()); err != nil {
    panic(err)
    }
    c.String(http.StatusOK, "pong")
    })
    r.Run() // listen and serve on 0.0.0.0:8080
    }
    ```