
获得徽章 0
Web应用。在领域驱动设计(DDD)和微服务等方面也有广泛应用。但是,像其他应用程序一样,当我们需要停止Gin Web服务时,必须处理关闭连接和释放内存等问题,以避免服务异常或不规范退出。
本文将介绍如何使用Gin框架优雅退出。
优雅退出的原理
传统的停止 Golang web 服务做法是调用关闭 TCP 连接的API。问题是如果此时有请求正在处理 HTTP 请求,则会因为其中的go协程未结束而退出,从而导致一些资源泄露等问题。
优雅停止的方法是监听系统信号(例如ctrl+c)后,关闭给定的HTTP服务器,等待活动连接(advisory TCP close)完成所有请求的数据交换并断开连接。这确保每个客户端都可以正确地关闭。
本文将介绍如何使用Gin框架优雅退出。
优雅退出的原理
传统的停止 Golang web 服务做法是调用关闭 TCP 连接的API。问题是如果此时有请求正在处理 HTTP 请求,则会因为其中的go协程未结束而退出,从而导致一些资源泄露等问题。
优雅停止的方法是监听系统信号(例如ctrl+c)后,关闭给定的HTTP服务器,等待活动连接(advisory TCP close)完成所有请求的数据交换并断开连接。这确保每个客户端都可以正确地关闭。
展开
评论
点赞
现在越来越多的公司在使用 Golang 语言进行开发。其上手容易学习成本低。使用 Golang 时有几个命令是我们经常会用到。在使用 Go 进行任何操作之前,您需要安装 Go 编译器。 您可以通过运行检查它是否已安装:
go version
如果你已经安装了,你应该可以看到其版本号,如果还没有安装,那可以直接进入官网进行安装:
go.dev
go version go1.18.2 darwin/arm64
如果你想检查一些与 Go 相关的环境变量,这个和开关很有关系,比如 GOROOT 或 GOPATH,直接执行命令 go env,查看这两个环境变量的配置。关于这两个环境变量的设置和说明,可查看这篇文章:理解了 GOPATH 和 GOROOT才能找出问题根源
开发环境搭建完成后,就可以开始进行编码,第一个你可能执行的命令应该是 :
go mod init <project name>
它将初始化一个 go.mod 文件,如果你做过 Java 开发,它类似于 pom.xml,如果你做过 JavaScript 开发,它类似于 package.json。其中基本是依赖包的引用的集合,
接下来就是安装一些在项目中可能会使用的使用的第三方库或框架:
go get <package name>
当你完成编码部分,想运行项目看看是否是预期一样运算结果时,需要执行命令:
go run . //一般以 main 文件为入口文件时,go run main
Go 更精巧的事是可以将整个代码编译称单个二进制文件,与 Java 或 C++ 等其他编译语言相比,编译时间也非常快。命令是:
go version
如果你已经安装了,你应该可以看到其版本号,如果还没有安装,那可以直接进入官网进行安装:
go version go1.18.2 darwin/arm64
如果你想检查一些与 Go 相关的环境变量,这个和开关很有关系,比如 GOROOT 或 GOPATH,直接执行命令 go env,查看这两个环境变量的配置。关于这两个环境变量的设置和说明,可查看这篇文章:理解了 GOPATH 和 GOROOT才能找出问题根源
开发环境搭建完成后,就可以开始进行编码,第一个你可能执行的命令应该是 :
go mod init <project name>
它将初始化一个 go.mod 文件,如果你做过 Java 开发,它类似于 pom.xml,如果你做过 JavaScript 开发,它类似于 package.json。其中基本是依赖包的引用的集合,
接下来就是安装一些在项目中可能会使用的使用的第三方库或框架:
go get <package name>
当你完成编码部分,想运行项目看看是否是预期一样运算结果时,需要执行命令:
go run . //一般以 main 文件为入口文件时,go run main
Go 更精巧的事是可以将整个代码编译称单个二进制文件,与 Java 或 C++ 等其他编译语言相比,编译时间也非常快。命令是:
展开
评论
点赞
作者(Cherry Mui、Austin Clements、Michael Pratt)建议向 Go GC 工具链增加对配置文件引导优化 (PGO) 的支持,可以使得工具链能根据运行时信息执行特定于应用程序和工作负载的优化。
说明了就是想提高性能,不改业务代码。
用什么来做
PGO 需要用户参与来收集配置文件并将其反馈到构建过程中才能优化。这是一个大问题。
最符合这个要求的,就是 pprof。最终敲定Go 团队将基于 runtime/pprof 来得到所需 profile,以此来完成 PGO。因为它符合:采集样本开销低、多系统兼容性强、Go 标准且被广泛使用的基准。
说明了就是想提高性能,不改业务代码。
用什么来做
PGO 需要用户参与来收集配置文件并将其反馈到构建过程中才能优化。这是一个大问题。
最符合这个要求的,就是 pprof。最终敲定Go 团队将基于 runtime/pprof 来得到所需 profile,以此来完成 PGO。因为它符合:采集样本开销低、多系统兼容性强、Go 标准且被广泛使用的基准。
展开
评论
点赞
年慢慢开始接触了Go语言,也在公司写了几个Go的生产项目。我是从Java转过来的。(其实也不算转,公司用啥,我用啥)在这个过程中,老是想用Java的思维写Go,在开始的一两个月,那是边写边吐槽。
丑陋的错误处理,没有流式处理,还竟然没有泛型,框架生态链不成熟,没有一家独大的类似Spring的框架。(其实现在写了快一年的Go,Go还是挺香的,哈哈)
今天,我来聊一下,我在我在写Go过程中用的最多orm框架gorm。
Java的orm
写过Java的基本都知道Mybatis,Mybatis-plus。
在Mybatis-plus中操作单表非常方便,通过QueryWrapper,对于单表的操作非常的丝滑,没有任何的思维负担。
类似下面这样:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(User::getUsername,"zhangsan").eq(User::getAge,18);
userMapper.selectList(queryWrapper);
Go的orm
这里的条件查询都需要开发手动来拼接字符串,如果项目比较大的话,就会看到漫天飞的SQL字段,维护起来非常麻烦。
丑陋的错误处理,没有流式处理,还竟然没有泛型,框架生态链不成熟,没有一家独大的类似Spring的框架。(其实现在写了快一年的Go,Go还是挺香的,哈哈)
今天,我来聊一下,我在我在写Go过程中用的最多orm框架gorm。
Java的orm
写过Java的基本都知道Mybatis,Mybatis-plus。
在Mybatis-plus中操作单表非常方便,通过QueryWrapper,对于单表的操作非常的丝滑,没有任何的思维负担。
类似下面这样:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(User::getUsername,"zhangsan").eq(User::getAge,18);
userMapper.selectList(queryWrapper);
Go的orm
这里的条件查询都需要开发手动来拼接字符串,如果项目比较大的话,就会看到漫天飞的SQL字段,维护起来非常麻烦。
展开
评论
点赞
统 (OS) 是计算机系统的心脏和灵魂,它管理着计算机的硬件和软件资源,并为用户提供与计算机交互的方式。传统上,C 和 Assembly 等语言因其低开销和 “接近机器码” 的特性而被用于开发操作系统。
但诸如 Go 等高级语言的兴起引入了一些特性,这些特性或许可以使开发操作系统等复杂软件变得更加容易。例如,类型安全、错误处理和并发性在开发操作系统时应该是有益的。
因此,采用像 Go 这样的高级语言来开发操作系统理应是自然选择,但为什么并没有成功的案例?
操作系统由不同的组件构成,它们负责不同的功能,可以使用不同的编程语言编写。
操作系统的核心是内核 (Kernel),它负责与硬件交互 —— 几乎都是采用 C 或汇编语言编写。至于面向用户的组件(例如 GUI 应用程序),可以采用任何语言编写。
例如,Android 采用 Java 编写用户层的
但诸如 Go 等高级语言的兴起引入了一些特性,这些特性或许可以使开发操作系统等复杂软件变得更加容易。例如,类型安全、错误处理和并发性在开发操作系统时应该是有益的。
因此,采用像 Go 这样的高级语言来开发操作系统理应是自然选择,但为什么并没有成功的案例?
操作系统由不同的组件构成,它们负责不同的功能,可以使用不同的编程语言编写。
操作系统的核心是内核 (Kernel),它负责与硬件交互 —— 几乎都是采用 C 或汇编语言编写。至于面向用户的组件(例如 GUI 应用程序),可以采用任何语言编写。
例如,Android 采用 Java 编写用户层的
展开
评论
点赞
名的硬核大佬 Russ Cox 表示他一直在研究这个问题,并表示十年的经验表明了当前语义的代价是很大的。
问题
案例一:取地址符
在 Go 语言中,我们写 for 语句时有时会出现运行和猜想的结果不一致。例如以下第一个案例的代码:
var all []*Item
for _, item := range items {
all = append(all, &item)
}
这段代码有问题吗?变量 all 内的 item 变量,存储进去的是什么? 是每次循环的 item 值吗?
实际上在 for 循环时,每次存入变量 all 的都是相同的 item,也就是最后一个循环的 item 值。
这是 Go 面试里经常出现的题目,结合 goroutine 更风骚,毕竟还会存在乱序输出等问题。
如果你想解决这个问题,就需要把程序改写成如
问题
案例一:取地址符
在 Go 语言中,我们写 for 语句时有时会出现运行和猜想的结果不一致。例如以下第一个案例的代码:
var all []*Item
for _, item := range items {
all = append(all, &item)
}
这段代码有问题吗?变量 all 内的 item 变量,存储进去的是什么? 是每次循环的 item 值吗?
实际上在 for 循环时,每次存入变量 all 的都是相同的 item,也就是最后一个循环的 item 值。
这是 Go 面试里经常出现的题目,结合 goroutine 更风骚,毕竟还会存在乱序输出等问题。
如果你想解决这个问题,就需要把程序改写成如
展开
评论
点赞
jy 们是从别的语言转 Go 的,比如 Java 、php 等,有兄弟在刚开始学的时候疑惑怎么能写出来优秀的代码。最近在项目中也 codereview 了不少 Go 语言的代码,有必要总结下代码规范,算是一个笔记记录了。
说在前面,这只是我们团队的一套规范而已。
今天我们聊一下 Go 的编码规范,大概分为几大模块,如注包/变量/常量命名、基本语法、函数、错误处理、心得等。
1. 代码风格
1.1 代码格式
代码必须用 gofmt 进行格式化,goland 可以配置,可以自行搜索一下配置
我们编写的代码每行应该不超过 120 个字符,超出部分用换行解决。
单个文件最大行数最大不超过 800 行.
单个函数最大行数不超过 80 行。
说在前面,这只是我们团队的一套规范而已。
今天我们聊一下 Go 的编码规范,大概分为几大模块,如注包/变量/常量命名、基本语法、函数、错误处理、心得等。
1. 代码风格
1.1 代码格式
代码必须用 gofmt 进行格式化,goland 可以配置,可以自行搜索一下配置
我们编写的代码每行应该不超过 120 个字符,超出部分用换行解决。
单个文件最大行数最大不超过 800 行.
单个函数最大行数不超过 80 行。
展开
评论
点赞
的最后一个形参才能使用...**操作符,使用它必须注意如下事项:
可变长参数必须在函数列表的最后一个;
把可变长参数当切片来解析,可变长参数没有没有值时就是nil切片
可变长参数的类型必须相同
func test(a int, b ...int){
return
}
既然我们的函数可以接收可变长参数,那么我们在传参的时候也可以传递切片使用**...**进行解包转换为参数列表,append方法就是最好的例子:
var sl []int
sl = append(sl, 1)
sl = append(sl, sl...)
append方法定义如下:
// slice = append(slice, elem1, elem2)
// slice = append(slice, anotherSlice...)
func append(slice []Type, elems .
可变长参数必须在函数列表的最后一个;
把可变长参数当切片来解析,可变长参数没有没有值时就是nil切片
可变长参数的类型必须相同
func test(a int, b ...int){
return
}
既然我们的函数可以接收可变长参数,那么我们在传参的时候也可以传递切片使用**...**进行解包转换为参数列表,append方法就是最好的例子:
var sl []int
sl = append(sl, 1)
sl = append(sl, sl...)
append方法定义如下:
// slice = append(slice, elem1, elem2)
// slice = append(slice, anotherSlice...)
func append(slice []Type, elems .
展开
评论
点赞
可以看到,作为黄色部分的 pnpm,在绝多大数场景下,包安装的速度都是明显优于 npm/yarn,速度会比 npm/yarn 快 2-3 倍。
对 yarn 比较熟悉的同学可能会说,yarn 不是有 PnP 安装模式吗?直接去掉 node_modules,将依赖包内容写在磁盘,节省了 node 文件 I/O 的开销,这样也能提升安装速度。(具体原理见这篇文章)
接下来,我们以这样一个仓库为例,我们来看一看 benchmark 数据,主要对比一下 pnpm 和 yarn PnP:
作者:神三元
链接:
juejin.cn
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
对 yarn 比较熟悉的同学可能会说,yarn 不是有 PnP 安装模式吗?直接去掉 node_modules,将依赖包内容写在磁盘,节省了 node 文件 I/O 的开销,这样也能提升安装速度。(具体原理见这篇文章)
接下来,我们以这样一个仓库为例,我们来看一看 benchmark 数据,主要对比一下 pnpm 和 yarn PnP:
作者:神三元
链接:
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
展开
评论
点赞
RPC的概念模型:User、User-Stub、RPC-Runtime、Server-Stub、Server
来自论文《Implementing Remote Procedure Calls》
IDL(Interface Definition Language) 文件
Thrift
Protobuf
生成代码
编解码(序列化/反序列化)
通信协议
应用层协议
网络通信
IO 网络模型
blocking IO
unblocking IO
IO multiplexing
signal driven IO
asynchronous IO
传输层协议
TCP
UDP
作者:青训营官方账号
链接:
juejin.cn
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来自论文《Implementing Remote Procedure Calls》
IDL(Interface Definition Language) 文件
Thrift
Protobuf
生成代码
编解码(序列化/反序列化)
通信协议
应用层协议
网络通信
IO 网络模型
blocking IO
unblocking IO
IO multiplexing
signal driven IO
asynchronous IO
传输层协议
TCP
UDP
作者:青训营官方账号
链接:
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
展开
评论
点赞