go语言web框架比较:gin vs iris vs echo _weixin_34217773的博客-CSDN博客


本站和网页 https://blog.csdn.net/weixin_34217773/article/details/88903089 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

go语言web框架比较:gin vs iris vs echo _weixin_34217773的博客-CSDN博客
go语言web框架比较:gin vs iris vs echo
weixin_34217773
于 2018-02-26 19:34:15 发布
2326
收藏
文章标签:
golang
java
json
原文链接:https://segmentfault.com/a/1190000013394345
版权
前言
由于golang提供了完善的net/http标准库,基于该标准库实现一个web框架的难度相比其他语言低了不少,所以go web框架简直就是百花齐放。从老牌的revel和beego,到新出的gin,和iris等,而且还有一些类似于chi这种router。个人一般小项目,尤其是中间件需要暴露一些http接口的,基本就使用chi即可。本次测试主要是gin iris echo 这三个框架。侧重在于高性能,从并发和json序列化和反序列化两个方面来测评,毕竟后台项目侧重的也就是这两个方面。
测试
测试环境说明
为了选择符合重IO的框架,现设定如下场景的demo,demo的具体要求如下:
打开日志功能(模拟正常业务时也会记录日志),在请求开始和结束时分别记录一条日志接口中用sleep暂停1秒,假设这里的网络IO操作(同时更容易从日志看出是否协程并发的行为)用POST接口做测试,接口中不进行任何处理,把接收到的body直接序列化返回(序列化和反序列化是框架最高频的动作)打开框架的accesslog功能
测试工具以及场景如下
测试工具使用经典的jmeter,直接使用GUI界面测试场景分为10线程并发,100线程并发,500线程并发,1000线程并发和1500线程并发所有结果都只看jmeter的聚合报告,重点查看吞吐量、时间和错误数所有demo启动的时候均启动单线程,异步框架不限制协程的数量,设置GOMAXPROCS=1所有测试均在本地,压测时长两分钟测试时采用POST请求,数据样本有565bytes、5KB、10KB、50KB和100KB,每个样本都要在不同并发线程上测试
测试代码
gin:
package main
import (
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
// Agent ...
type Agent struct {
AgentID string `json:"agent_id"`
QueuedAt string `json:"queued_at"`
QueuedBy string `json:"queued_by"`
// Details ...
type Details struct {
EventID string `json:"event_id"`
Endpoint string
Metric string
Content string
Priority int
Status string
// Test1 ...
type Test1 struct {
Agent Agent
Details Details
Description string
EventType string `json:"event_type"`
ServiceKey string `json:"service_key"`
// Test2 test2
type Test2 struct {
Data []*Test1
func main() {
r := gin.New()
// Global middleware
// Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
// By default gin.DefaultWriter = os.Stdout
r.Use(gin.Logger())
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.POST("/v1/test", func(c *gin.Context) {
var test Test1
if err := c.BindJSON(&test); err == nil {
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
c.JSON(http.StatusOK, test)
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
})
r.POST("/v2/test", func(c *gin.Context) {
var test Test2
if err := c.BindJSON(&test); err == nil {
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
c.JSON(http.StatusOK, test)
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
})
r.POST("/v3/test", func(c *gin.Context) {
var test Test2
if err := c.BindJSON(&test); err == nil {
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
c.JSON(http.StatusOK, test)
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
})
r.POST("/v4/test", func(c *gin.Context) {
var test Test2
if err := c.BindJSON(&test); err == nil {
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
c.JSON(http.StatusOK, test)
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
})
r.Run() // listen and serve on 0.0.0.0:8080
iris:
package main
import (
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/middleware/logger"
// Agent ...
type Agent struct {
AgentID string `json:"agent_id"`
QueuedAt string `json:"queued_at"`
QueuedBy string `json:"queued_by"`
// Details ...
type Details struct {
EventID string `json:"event_id"`
Endpoint string
Metric string
Content string
Priority int
Status string
// Test1 ...
type Test1 struct {
Agent Agent
Details Details
Description string
EventType string `json:"event_type"`
ServiceKey string `json:"service_key"`
// Test2 test2
type Test2 struct {
Data []*Test1
func main() {
app := iris.New()
app.Use(logger.New())
app.Get("/ping", func(c iris.Context) {
c.WriteString("pong")
})
app.Post("/v1/test", func(c iris.Context) {
var test Test1
if err := c.ReadJSON(&test); err == nil {
app.Logger().Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
app.Logger().Println("=========================end io=======================")
c.JSON(test)
} else {
c.WriteString("failure")
})
app.Post("/v2/test", func(c iris.Context) {
var test Test2
if err := c.ReadJSON(&test); err == nil {
app.Logger().Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
app.Logger().Println("=========================end io=======================")
c.JSON(test)
} else {
c.WriteString("failure")
})
app.Post("/v3/test", func(c iris.Context) {
var test Test2
if err := c.ReadJSON(&test); err == nil {
app.Logger().Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
app.Logger().Println("=========================end io=======================")
c.JSON(test)
} else {
c.WriteString("failure")
})
app.Post("/v4/test", func(c iris.Context) {
var test Test2
if err := c.ReadJSON(&test); err == nil {
app.Logger().Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
app.Logger().Println("=========================end io=======================")
c.JSON(test)
} else {
c.WriteString("failure")
})
// Start the server using a network address.
app.Run(
iris.Addr(":8080"),
// disables updates:
iris.WithoutVersionChecker,
// skip err server closed when CTRL/CMD+C pressed:
iris.WithoutServerError(iris.ErrServerClosed),
// enables faster json serialization and more:
iris.WithOptimizations)
echo:
package main
import (
"log"
"net/http"
"time"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
// Agent ...
type Agent struct {
AgentID string `json:"agent_id"`
QueuedAt string `json:"queued_at"`
QueuedBy string `json:"queued_by"`
// Details ...
type Details struct {
EventID string `json:"event_id"`
Endpoint string
Metric string
Content string
Priority int
Status string
// Test1 ...
type Test1 struct {
Agent Agent
Details Details
Description string
EventType string `json:"event_type"`
ServiceKey string `json:"service_key"`
// Test2 test2
type Test2 struct {
Data []*Test1
func main() {
// Echo instance
app := echo.New()
// Middleware
app.Use(middleware.Logger())
// Routes
app.GET("/ping", func(c echo.Context) error {
return c.String(200, "pong")
})
app.POST("/v1/test", func(c echo.Context) error {
var test Test1
if err := c.Bind(&test); err != nil {
return err
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
return c.JSON(http.StatusOK, test)
})
app.POST("/v2/test", func(c echo.Context) error {
var test Test2
if err := c.Bind(&test); err != nil {
return err
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
return c.JSON(http.StatusOK, test)
})
app.POST("/v3/test", func(c echo.Context) error {
var test Test2
if err := c.Bind(&test); err != nil {
return err
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
return c.JSON(http.StatusOK, test)
})
app.POST("/v4/test", func(c echo.Context) error {
var test Test2
if err := c.Bind(&test); err != nil {
return err
log.Println("========================start io=====================")
time.Sleep(time.Duration(1) * time.Second)
log.Println("=========================end io=======================")
return c.JSON(http.StatusOK, test)
})
// Start server
app.Logger.Fatal(app.Start(":8080"))
以上除了echo之外,其他三个都原生支持了jsoniter 这个性能的json序列化库,都启用。等待1s,模拟io读写等待
测试对比
由于要测试5种body样本,4种场景,4个框架,因此把重点数据筛选出来(吞吐量、错误率和99%Line,重要性依次递减),结果都绘制了图形,方便比对查看。
565bytes下测试结果
5KB下测试结果
10KB下测试结果
50KB下测试结果
100KB下测试结果
总结
综合以上各个测试结果可以看出,gin以及iris都是非常优秀的框架,gin的优势比其他稍微大点,iris次之,而echo相应差一点。本次测试只是简单测试了一下3个框架的并发和json相关。对比结果,不包括生态和工具的完善度等等。如果测试有什么不完善的地方,欢迎交流。另外欢迎大家试用和star另外一个web框架baa,为了避嫌我没有贴出baa的数据,性能测试处于gin之后和iris之间。
weixin_34217773
关注
关注
点赞
收藏
评论
go语言web框架比较:gin vs iris vs echo
前言由于golang提供了完善的net/http标准库,基于该标准库实现一个web框架的难度相比其他语言低了不少,所以go web框架简直就是百花齐放。从老牌的revel和beego,到新出的gin,和iris等,而且还有一些类似于chi这种router。个人一般小项目,尤其是中间件需要暴露一些http接口的,基本就使用chi即可。本次...
复制链接
扫一扫
Gin和Iris等Web框架及redis与go的连接使用
姚军
12-28
1132
参考链接
首先安装go
然后配置环境变量
Windows
修改环境变量和网络代理
前面两句相当于修改环境变量中的参数,然后才能下载。
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
go get -u github.com/gin-gonic/gin
go get github.com/kataras/iri...
函数怎么屏蔽其他echo_Go框架解析:echo
weixin_39976733的博客
11-22
42
前言今天是我golang框架阅读系列第四篇文章,今天我们主要看看echo的框架执行流程。关于golang框架生命周期源码阅读下面是我的计划:计划状态Go框架解析:beego✅doneGo框架解析:iris✅doneGo框架解析:gin✅doneGo框架解析:echo✅doneGo框架解析:revel✈️doingGo框架解析:Martini️️✈️doing再完成各个golang框架生命...
参与评论
您还未登录,请先
登录
后发表或查看评论
第一个 GoWeb 程序,三款主流框架 Beego、Gin 和 Iris 快速入门
最新发布
蜗牛的博客
11-21
324
第一个 GoWeb 程序,三款主流框架 Beego、Gin 和 Iris 快速入门
golang (iris/gin/beego等) 编译运行热编译工具(bee/gowatch)
小月肖的肖
02-12
5304
强烈推荐beego中的bee工具 也可仿照其源码写一个
我平时用的iris 用的都是bee run 生产环境建议go build运行
go get github.com/beego/bee
Bee is a Fast and Flexible tool for managing your Beego Web Application.
Usage:
bee command [argum...
2019 Go 三款主流框架 —— Gin Beego Iris 选型对比
热门推荐
u012925833的博客
10-11
5万+
1. 常见框架
1.1 框架排名
Gin 31k [Lite]
Beego 22k
Iris 16k
Echo 15k [Lite]
Revel 11k
Martini 10k [×]
buffalo 5k [Lite]
1.2 框架特性
Gin:
Gin 是一个用 Go (Golang) 编写的 web 框架。...
Go语言框架:Beego vs Gin 的区别
weixin_30790841的博客
07-07
7008
前言:
一切语言、技术或者框架,本质都是工具,工具的价值在于为使用者提供竞争优势。
一、Beego和Gin全方位比较
MVC
Beego支持完整的MVC, Gin不支持完整的MVC(需要开发者自己实现MVC)
路由&Session
Beego支持正则路由, Gin不支持正则路由
Beego支持Session, Gin不支持Session(需要安装另外的包)...
Go框架比较:goframe、beego、iris和gin
weixin_50196917的博客
06-30
2147
由于工作需要,这些年来也接触了不少的开发框架,Golang的开发框架比较多,不过基本都是Web”框架”为主。这里稍微打了个引号,因为大部分”框架”从设计和功能定位上来讲,充其量都只能算是一个组件,需要项目使用的话得自己四处再去找找其他的组件,或者自己造轮子。如果用于Web开发,这些”框架”的Web开发能力均已完备,无太大差别,且均是自标准库net/http.Server的二次封装。由于框架众多,这里笔者只选择了几个曾做过技术选型评估、较为熟悉,且目前比较流行和典型的Golang”框架”,从适用于业务项目开发
golang后台管理系统Beego+Layui框架搭建教程
weixin_50196917的博客
04-17
1173
一款 Go 语言基于Beego、Layui、MySQL等框架精心打造的一款模块化、高性能、企业级的敏捷开发框架,本着简化开发、提升开发效率的初衷触发,框架自研了一套个性化的组件,实现了可插拔的组件式开发方式:单图上传、多图上传、下拉选择、开关按钮、单选按钮、多选按钮、图片裁剪等等一系列个性化、轻量级的组件,是一款真正意义上实现组件化开发的敏捷开发框架。...
Iris+Vue的前后端分离开源项目
weixin_50196917的博客
05-28
198
项目介绍
一款 Go 语言基于Iris、Vue、ElementUI、MySQL等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可快速搭建前后端分离后台管理系统,本着简化开发、提升开发效率的初衷,框架自研了一套个性化的组件,实现了可插拔的组件式开发方式,同时为了敏捷快速开发,框架特地集成了代码生成器,完全自主研发了自定义GO后端服务模板和前端Vue自定义模板,可以根据已建好的表结构,可以快速的一键生成整个模块的所有代码和增删改查等等功能业务,真正实现了低代码开发方式,极大的节省了人力成
Golang 微框架 Gin 简介
weixin_30699463的博客
08-22
2356
框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了。成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应手的时候,可以尝试改造一些框架,或是自己创造一个。
曾经我以为Python世界里的框架已经够多了,后来发现相比golang简直小巫见大巫。golang提供的net/http库已经很好了,对于...
Golang框架选型比较: goframe, beego, iris和gin
nantish的博客
01-29
9161
由于工作需要,这些年来也接触了不少的开发框架,Golang的开发框架比较多,不过基本都是Web"框架"为主。这里稍微打了个引号,因为大部分"框架"从设计和功能定位上来讲,充其量都只能算是一个组件,需要项目使用的话得自己四处再去找找其他的组件,或者自己造轮子。如果用于Web开发,这些"框架"的Web开发能力均已完备,无太大差别,且均是自标准库net/http.Server的二次封装。由于框架众多,这里笔者只选择了几个曾做过技术选型评估、较为熟悉,且目前比较流行和典型的Golang"框架",从适用于业务项目开发
go websocket游戏框架_使用iris和websocket开发简单的页面访问次数记录功能
weixin_42603332的博客
02-03
376
引言  Iris 框架是用 Go 编写的一款高性能 web 框架,它的性能仅次于 gin,但高于 beego 框架。Iris 框架里内置 websocket 模块,可以实现 websocket 服务器,核心是封装了 neffos 开源模块。  Websocket 可实现全双工通信,也就是客户端和服务器在建立连接之后,可以互相接收和发送消息,具有长连接的特性。可以利用 websocket 实现移动端...
iris文件服务器,Iris MVC · GO WEB IRIS入门到入土(GOWeb系列教程) · 看云
weixin_42118423的博客
08-11
257
Iris MVC===### 目录结构:~~~.├── datamodels // 数据模型├── repositories // dao层├── services // 服务层├── main.go // 入口文件└── web├── controllers└── views~~~#### 入口文件~~~package mainimport "github.com/kataras/iris"f...
Iris在log中打印请求信息和返回结果 方便调试
情怀中的释然~
10-24
3147
Iris这个框架相关的资料太少,进行任何封装操作都只能点进去看源码进行操作,总结了下打印日志信息的方式,留给有需要的人
大致思路
1、将每次请求返回的数据保存在ctx的values中
2、自定义日志中间件,每次请求done之后调用中间件
3、在日志中间件中打印请求数据
将每次请求返回的数据保存在ctx的values中
import (
"xiaoge/src/core"
// Test...
golang iris mysql_iris 真的是最快的Golang 路由框架吗?
weixin_33195162的博客
02-15
209
对各种Go http路由框架的比较, Iris明显胜出,它的性能远远超过其它Golang http路由框架。但是,在真实的环境中,Iris真的就是最快的Golang http路由框架吗?Benchmark测试分析在那篇文章中我使用的是Julien Schmidt的 测试代码,他模拟了静态路由、Github API、Goolge+ API、Parse API的各种情况,因为这些API是知名网站的开放...
go语言有哪些web框架
weixin_50196917的博客
07-06
1072
由于工作需要,这些年来也接触了不少的开发框架,Golang的开发框架比较多,不过基本都是Web”框架”为主。这里稍微打了个引号,因为大部分”框架”从设计和功能定位上来讲,充其量都只能算是一个组件,需要项目使用的话得自己四处再去找找其他的组件,或者自己造轮子。如果用于Web开发,这些”框架”的Web开发能力均已完备,无太大差别,且均是自标准库net/http.Server的二次封装。由于框架众多,这里笔者只选择了几个曾做过技术选型评估、较为熟悉,且目前比较流行和典型的Golang”框架”,从适用于业务项目开发
GO语言gin框架初步介绍
weixin_48364360的博客
01-08
520
1.下载gin框架
go get -u github.com/gin-gonic/gin
当无法下载时,大概率是被墙了
需要配置环境变量
go env -w GOPROXY=https://goproxy.io,direct
go env -w GOPRIVATE=*.corp.example.com
不建议使用
GO111MODULE=on
因为创建其他项目的时候不能自动导入已下好的库
2.创造路由
r := gin.Default() //默认中间件的路由
r := gin.new()
Go框架解析-Gin
TIGERB的技术博客
07-08
309
前言今天是我golang框架阅读系列第三篇文章,今天我们主要看看gin的框架执行流程。关于golang框架生命周期源码阅读下面是我的计划:计划状态Go框架解析-beegodoneGo框架...
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
©️2022 CSDN
皮肤主题:大白
设计师:CSDN官方博客
返回首页
weixin_34217773
CSDN认证博客专家
CSDN认证企业博客
码龄7年
暂无认证
152
原创
周排名
142万+
总排名
104万+
访问
等级
6444
积分
4773
粉丝
214
获赞
17
评论
990
收藏
私信
关注
热门文章
SSL踩坑ERR_SSL_VERSION_OR_CIPHER_MISMATCH
27130
关于VUE中v-for循环的dom使用ref获取不到问题
14509
怎么设置百度网盘免验证登陆?
13662
通达信公式破解
13378
idea unknow facet type web 解决方案
12970
最新评论
如果虚函数在基类与子类名字相同,而参数类型不同不会进行迟后联编
嘻·嘻:
那个,如果test函数中,先是float调用b.fn(float)再调用bn(int),会输出in subclass 吗
[Winfrom]Cefsharp配置与初始化
weixin_43386952:
博主您好,我也在用winform内嵌cefsharp作为浏览器跳转网站,但是发现了一个难题,就是首次加载页面的时候特别慢,加载过一次后的其他加载就正常了,这个您知道是如何引起的吗?应该如何避免呢?
通达信公式破解
爱编程的懒洋洋:
通达信公式加密破解器,可以破解公式密码。下载地址:https://url92.ctfile.com/d/4029992-6433014-2fb917(访问密码:8508)
希望相对路径关于background-image:url()在样式表里设置后有不管用的办法
Artemis711:
如果img和css是两个同级文件夹,在css/css1.css里设样式的时候,图片是位于css1.css的上一级文件夹,所以要“../”返回到上一级文件夹
希望相对路径关于background-image:url()在样式表里设置后有不管用的办法
Artemis711:
同问,我现在也是遇到这个问题,书上background:url()可以设相对路径,博主知道答案了嘛?
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
cpp 线程传递参数
SFTP文件上传下载
VC中精确获取字符串长宽
2019年396篇
2018年648篇
2017年1032篇
2016年548篇
2015年421篇
2014年321篇
2013年314篇
2012年245篇
2011年204篇
2010年138篇
2009年115篇
2008年88篇
2007年72篇
2006年46篇
2005年15篇
2004年7篇
目录
目录
最新文章
cpp 线程传递参数
SFTP文件上传下载
VC中精确获取字符串长宽
2019年396篇
2018年648篇
2017年1032篇
2016年548篇
2015年421篇
2014年321篇
2013年314篇
2012年245篇
2011年204篇
2010年138篇
2009年115篇
2008年88篇
2007年72篇
2006年46篇
2005年15篇
2004年7篇
目录
评论
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。
余额充值