gf/gin/beego性能测试

This commit is contained in:
John
2018-05-28 17:02:53 +08:00
parent 0dd44ef33b
commit 046d1c4a5b
11 changed files with 78 additions and 29 deletions

View File

@ -24,7 +24,13 @@ type Client struct {
// http客户端对象指针
func NewClient() (*Client) {
return &Client{}
return &Client{
http.Client {
Transport: &http.Transport {
DisableKeepAlives: true,
},
},
}
}
// 设置请求过期时间

View File

@ -21,7 +21,7 @@ type Request struct {
http.Request
parsedGet *gtype.Bool // GET参数是否已经解析
parsedPost *gtype.Bool // POST参数是否已经解析
values map[string][]string // GET参数
queries map[string][]string // GET参数
exit *gtype.Bool // 是否退出当前请求流程执行
Id int // 请求id(唯一)
Server *Server // 请求关联的服务器对象
@ -32,6 +32,8 @@ type Request struct {
EnterTime int64 // 请求进入时间(微秒)
LeaveTime int64 // 请求完成时间(微秒)
Param interface{} // 开发者自定义参数
parsedHost *gtype.String // 解析过后不带端口号的服务器域名名称
clientIp *gtype.String // 解析过后的客户端IP地址
}
// 创建一个Request对象
@ -39,13 +41,15 @@ func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request {
request := &Request{
parsedGet : gtype.NewBool(),
parsedPost : gtype.NewBool(),
values : make(map[string][]string),
queries : make(map[string][]string),
exit : gtype.NewBool(),
Id : s.servedCount.Add(1),
Server : s,
Request : *r,
Response : newResponse(w),
EnterTime : gtime.Microsecond(),
parsedHost : gtype.NewString(),
clientIp : gtype.NewString(),
}
// 会话处理
request.Cookie = GetCookie(request)
@ -58,11 +62,11 @@ func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request {
// 初始化GET请求参数
func (r *Request) initGet() {
if !r.parsedGet.Val() {
if len(r.values) == 0 {
r.values = r.URL.Query()
if len(r.queries) == 0 {
r.queries = r.URL.Query()
} else {
for k, v := range r.URL.Query() {
r.values[k] = v
r.queries[k] = v
}
}
}
@ -87,7 +91,7 @@ func (r *Request) Get(k string) string {
// 获得指定名称的get参数列表
func (r *Request) GetQuery(k string) []string {
r.initGet()
if v, ok := r.values[k]; ok {
if v, ok := r.queries[k]; ok {
return v
}
return nil
@ -131,7 +135,7 @@ func (r *Request) GetQueryMap(defaultMap...map[string]string) map[string]string
r.initGet()
m := make(map[string]string)
if len(defaultMap) == 0 {
for k, v := range r.values {
for k, v := range r.queries {
m[k] = v[0]
}
} else {
@ -304,19 +308,31 @@ func (r *Request) IsExited() bool {
// 获取请求的服务端IP/域名
func (r *Request) GetHost() string {
array, _ := gregx.MatchString(`(.+):(\d+)`, r.Host)
if len(array) > 1 {
return array[1]
host := r.parsedHost.Val()
if len(host) == 0 {
array, _ := gregx.MatchString(`(.+):(\d+)`, r.Host)
if len(array) > 1 {
host = array[1]
} else {
host = r.Host
}
r.parsedHost.Set(host)
}
return r.Host
return host
}
// 获取请求的客户端IP地址
func (r *Request) GetClientIp() string {
array, _ := gregx.MatchString(`(.+):(\d+)`, r.RemoteAddr)
if len(array) > 1 {
return array[1]
ip := r.clientIp.Val()
if len(ip) == 0 {
array, _ := gregx.MatchString(`(.+):(\d+)`, r.RemoteAddr)
if len(array) > 1 {
ip = array[1]
} else {
ip = r.RemoteAddr
}
r.clientIp.Set(ip)
}
return r.RemoteAddr
return ip
}

View File

@ -91,17 +91,12 @@ func (s *Server) setHookHandler(pattern string, hook string, item *HandlerItem)
// 事件回调 - 检索动态路由规则
// 并按照指定hook回调函数的优先级及注册顺序进行调用
func (s *Server) callHookHandler(r *Request, hook string) {
// 缓存清空时是直接修改属性,因此必须使用互斥锁
s.hhcmu.RLock()
defer s.hhcmu.RUnlock()
var hookItems []*hookCacheItem
cacheKey := s.handlerHookKey(r.GetHost(), r.Method, r.URL.Path, hook)
return
if v := s.hooksCache.Get(cacheKey); v == nil {
hookItems = s.searchHookHandler(r, hook)
if hookItems != nil {
@ -113,7 +108,7 @@ func (s *Server) callHookHandler(r *Request, hook string) {
if hookItems != nil {
for _, item := range hookItems {
for k, v := range item.values {
r.values[k] = v
r.queries[k] = v
}
item.faddr(r)
}

View File

@ -16,7 +16,7 @@ import (
// handler缓存项根据URL.Path进行缓存因此对象中带有缓存参数
type handlerCacheItem struct {
item *HandlerItem // 准确的执行方法内存地址
item *HandlerItem // 准确的执行方法内存地址
values map[string][]string // GET解析参数
}
@ -39,7 +39,7 @@ func (s *Server) getHandler(r *Request) *HandlerItem {
}
if handlerItem != nil {
for k, v := range handlerItem.values {
r.values[k] = v
r.queries[k] = v
}
r.Router = handlerItem.item.router
return handlerItem.item
@ -228,12 +228,12 @@ func (s *Server) searchHandlerDynamic(r *Request) *handlerCacheItem {
for e := lists[i].Front(); e != nil; e = e.Next() {
item := e.Value.(*HandlerItem)
if strings.EqualFold(item.router.Method, gDEFAULT_METHOD) || strings.EqualFold(item.router.Method, r.Method) {
regrule, names := s.patternToRegRule(item.router.Uri)
if gregx.IsMatchString(regrule, r.URL.Path) {
rule, names := s.patternToRegRule(item.router.Uri)
if gregx.IsMatchString(rule, r.URL.Path) {
handlerItem := &handlerCacheItem{item, nil}
// 如果需要query匹配那么需要重新解析URL
if len(names) > 0 {
if match, err := gregx.MatchString(regrule, r.URL.Path); err == nil {
if match, err := gregx.MatchString(rule, r.URL.Path); err == nil {
array := strings.Split(names, ",")
if len(match) > len(array) {
handlerItem.values = make(map[string][]string)

View File

@ -21,12 +21,12 @@ func main() {
go func(clientId int) {
url := "http://127.0.0.1:8199/"
for i := 0; i < requestMax; i++ {
//url = fmt.Sprintf("http://127.0.0.1:8199/%d_%d", clientId, i)
url = fmt.Sprintf("http://127.0.0.1:8199/%d_%d", clientId, i)
if c, e := ghttp.Get(url); e == nil {
//fmt.Println(string(c.ReadAll()))
c.Close()
successNum.Add(1)
} else {
fmt.Println(e)
failureNum.Add(1)
}
}

View File

@ -0,0 +1,16 @@
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.Use(gin.Recovery())
r.GET("/:name", func(c *gin.Context) {
c.String(http.StatusOK, c.Param("name"))
})
r.Run(":8199")
}

View File

@ -0,0 +1,16 @@
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.Use(gin.Recovery())
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "哈喽世界!")
})
r.Run(":8199")
}