感谢高级架构师的回应,他对go语言的并发性和经验有深刻的理解
我有一个自定义设备来处理,处理和响应传入的客户端请求,服务器只是将所有传入的请求,request
和responseWriter
包装在一个对象中并委托给设备。
我根据单元测试(向localhost生成1000 http请求)观察到的问题是所有请求都按顺序处理,而不是同时处理,就像它们在
中一样每个请求比前一个请求花费的时间更多,只是告诉我它是一个队列。例如,如果基于数据库的请求需要200 ms
。
Request 1 -> taking 200 ms
Request 2 -> taking 400 ms
Request 3 -> taking 600 ms
每个请求都在等待上一个请求完成,在将传入的请求委托给设备时,我没有做正确的事情,所以我准备了一个简化的版本,它简单地解码JWT令牌并响应客户端,请运行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 request
和responseWriter
type Request struct {
ResponseWriter http.ResponseWriter
Request *http.Request
}
ihandler.go 设备界面
type IHandler interface {
Handle(request *Request)
}
test / token_test.go 这将显示每个连续的请求所花费的时间比前一个更多
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.\n", 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())
}
最好download the project并进行测试。我怀疑问题出在server.go(第24行)。我没有以正确的方式委托请求,他们只是在排队。
我正在寻找的解决方案是如何同时委派/转发传入的请求。