dongqian3198 2017-03-24 23:23
浏览 88

转发传入的HTTP请求正在排队

Appreciate a response from a senior level architect who has a deep understanding of concurrency and experience in go language

I've a custom apparatus to handle, process and respond to incoming client requests and server is simply wrapping all the incoming requests, the request and responseWriter in an object and delegating to the apparatus.

The problem I'm observing based on my unit tests (spawning 1000 http request to localhost) is that all the requests are processed in sequence instead concurrently, it's like they are in

Each request is taking more time than the previous one simply telling me it's a queue. If for example a database based request takes 200 ms.

Request 1 -> taking 200 ms
Request 2 -> taking 400 ms
Request 3 -> taking 600 ms

Each request is waiting for the previous request to finish, I'm not doing something right when it comes to delegating incoming requests to the apparatus so I've prepared a trimmed down version that simply decodes the JWT token and responds to the client, please run test/token_test.go. Download Project

application.go

func main() {
        a := delegate.Apparatus{}
        a.Run()
}

apparatus.go

type Apparatus struct {}

func (a *Apparatus) Run() { // initialize the server
        server := Server{}
        server.SetDelegate(a) // tell server to forward requests to itself
        server.StartServer() // start the server
}

func (a *Apparatus) Handle(request *Request) { // interface impl
        a.RenewToken(request) // delegate request to a time consuming func
}

server.go

type Server struct {}

func (s *Server) StartServer() {
        http.HandleFunc("/", handler)
        fmt.Println("Server Listening at 8080")
        err := http.ListenAndServe(":8080", nil)
        if err != nil {
                    log.Fatal(err)
        }
}

func handler(w http.ResponseWriter, r *http.Request) { // delegate to apparatus
        delegate.Handle(&Request{ResponseWriter: w, Request: r})
}

func (s *Server) SetDelegate(d IHandler) {
        delegate = d
}

request.go wrapper for the request and responseWriter

type Request struct {
        ResponseWriter http.ResponseWriter
        Request        *http.Request
}

ihandler.go interface for the apparatus

type IHandler interface {
        Handle(request *Request)
}

test/token_test.go this will show each successive request is taking more and more time than the previous one

func MakeRequest(ch chan<-int, index int) {
        t0 := time.Now()
        response, _ := http.Get("http://localhost:8080?authToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Mjg4LCJuYmYiOjE0NDQ0Nzg0MDAsInJhbmQiOjAuOTI2OTg2ODAzNTc0NDE0Mn0.3HC8lEDGlui_sOtkeMn52Wnt9HUuH4lFbk7ubdUK_Z4&index=" + strconv.Itoa(index))
        t1 := time.Now()
        ch <- response.StatusCode
        fmt.Printf("The call took %v to run.
", t1.Sub(t0))
}

func TestConcurrent(t *testing.T) {
        start := time.Now()
        ch := make(chan int)
        max := 1000

        for i:=0; i<max; i++ {
                    go MakeRequest(ch, i)
        }

        for i:=0; i<max; i++ {
                    if <-ch != 200 {t.Error("Expecting status code 200")}
        }
        fmt.Printf("%.2fs elapsed", time.Since(start).Seconds())
}

It's best to download the project and test. I suspect the problem is in the server.go (line 24). I'm not delegating the request in a right way and they are simply queuing up.

Solution I'm looking for is how can I delegate/forward the incoming requests concurrently.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥100 为什么这个恒流源电路不能恒流?
    • ¥15 有偿求跨组件数据流路径图
    • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
    • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
    • ¥15 CSAPPattacklab
    • ¥15 一直显示正在等待HID—ISP
    • ¥15 Python turtle 画图
    • ¥15 stm32开发clion时遇到的编译问题
    • ¥15 lna设计 源简并电感型共源放大器
    • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)