Go
文章平均质量分 67
canger_
Linux C/C++、golang、云原生
展开
-
grpc长连接keepalive
背景项目中碰到了grpc双向流和单向流出现了服务端流context报错:context cancel error,而客户端无感知连接断开,依然认为还在连接中,导致数据传输中断。遇到这种情况从以下几个维度去思考问题发生的可能:网络是否稳定,能否复现客户端和服务端是否有对context进行cancel客户端和服务端是否有去处理context的cancel信号由于出现的问题不是在开发环境中,因此开始只能看日志进行排查,但是日志中只得到了服务端会收到context的cancel信号,而客户端没有任何原创 2022-04-11 11:24:57 · 4422 阅读 · 0 评论 -
浅谈流量限制
I/O密集型和CPU密集型对于IO/Network瓶颈类的程序,其表现是网卡/磁盘IO会先于CPU打满,这种情况即使优化CPU的使用也不能提高整个系统的吞吐量,只能提高磁盘的读写速度,增加内存大小,提升网卡的带宽来提升整体性能。而CPU瓶颈类的程序,则是在存储和网卡未打满之前CPU占用率先到达100%,CPU忙于各种计算任务,IO设备相对则较闲。无论哪种类型的服务,在资源使用到极限的时候都会导致请求堆积,超时,系统hang死,最终伤害到终端用户。对于分布式的Web服务来说,瓶颈还不一定总在系统内部,也有原创 2022-03-24 15:15:02 · 356 阅读 · 0 评论 -
Golang内存逃逸
逃逸分析内存逃逸:栈上的内存逃逸到了堆上的现象就称为内存逃逸概念程序在编译阶段根据代码来确认哪些变量分配在栈区,哪些变量分配在堆区。这样可以防止过多内存在堆上分配,减轻GC压力以及程序STW的时间原理指向栈对象的指针不能存储在堆中指向栈对象的指针不能超过该对象的存活期,也就是指针不能再栈对象被销毁后依然存活如何查看通过如下方式编译代码可以看到逃逸分析go build -gcflags='-m -m -l' -m -m 能看到所有编译器优化-l 禁用掉内联优化分析原创 2022-03-15 17:15:31 · 1074 阅读 · 0 评论 -
logrus设置日志格式与输出函数名
参考:https://juejin.cn/post/6844904061393698823普通日志设置func InitLogger() { level := GetLogLevel(viper.GetString("LOG_LEVEL")) log.SetLevel(level) formatter := &log.TextFormatter{ ForceColors: true,//设置颜色 FullTimestamp: .原创 2022-01-26 10:30:56 · 711 阅读 · 0 评论 -
Golang select优先级执行
select关键词go语言中select关键词用于监听case语句对应的chan,并执行其下相应的代码,直到case下的代码执行结束才会执行另一个发生的chan下面的代码。有点类似于switch。select {case x := <-ch1: fmt.Println(x)case ch2 <- 1: fmt.Println("push 1")}空selectselect{ }空的 select 语句会直接阻塞当前的goroutine,使得该gorout原创 2022-01-10 14:44:28 · 1981 阅读 · 0 评论 -
Gorm V2的使用感受和Save方法
Gorm V2的使用感受和Save方法和v1对比gorm-v2不支持多表情况下软硬删除的混合链式调用,否则会panicgorm-v2的create如果在select后调用,会出现插入空值的情况,可以通过select().create或者用db.session来解决https://github.com/go-gorm/gorm/issues/4778gorm-v2不需要subQuery了gorm-v2没有newScope方法来获取表名了给我目前最大的方便:可以进行批量插原创 2021-12-30 17:15:34 · 4480 阅读 · 0 评论 -
golang - sync.Map
Go语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全的// 创建一个int到int的映射m := make(map[int]int)// 开启一段并发代码go func() { // 不停地对map进行写入 for { m[1] = 1 }}()// 开启一段并发代码go func() { // 不停地对map进行读取 for { _ = m[1] }}()// 无限循环,原创 2021-12-02 11:48:26 · 245 阅读 · 0 评论 -
Go语言一些容易踩坑的地方
1、可变参数是空接口类型func main() { var a = []interface{}{1, 2, 3} fmt.Println(a) fmt.Println(a...)}不管是否展开,编译器都无法发现错误,但是输出是不同的:[1 2 3]1 2 32、数组是值传递在函数调用参数中,数组是值传递,无法通过修改数组类型的参数返回结果,因此必要时使用切片3、map遍历顺序不固定map是一种hash表的实现,每次遍历的顺序可能都不一样4、返回值被屏原创 2021-12-02 11:45:40 · 548 阅读 · 0 评论 -
浅谈分布式的负载均衡
一、常见的负载均衡思路1.1、按顺序挑:round robin式,例如上次选了第一台,那么这次就选第二台,下次第三台;如果到了最后一台,那么下次从第一台开始。1.2、随机挑一个:每次都随机挑,真随机伪随机均可。假设选择了第x台机器,那么x可被描述为rand.Intn()%n1.3、根据某种权重挑选对下游节点进行排序,选择权重最大/小那一个实际场景下我们不可能无脑轮询或者无脑随机,如果对下游请求失败了,我们还需要某种机制来进行重试,如果纯粹的随机算法,存在一定可能性下次仍然随机到这次的问题原创 2021-12-02 11:41:32 · 2220 阅读 · 0 评论 -
分布式id生成器
分布式id生成一、 MySQL自增ID二、Twitter的snowflake算法2.1 snowflake的id生成首先确定我们的数值是64位,int64类型,被划分为五部分:第一个bit位不用,代表符号位用41位来表示收到请求时的时间戳,单位为毫秒5位数表示数据中心的ID再5位数表示机器的实例ID最后是12位的循环自增ID,到达 1111 1111 1111 后会归0这样的机制可以支持我们在同一台机器上,同一毫秒内产生2^12 = 4096条消息,一秒则可以生成409.6w条消息,原创 2021-11-11 14:55:30 · 516 阅读 · 0 评论 -
GO&CGO的条件编译
GO条件编译go build 参数附加参数备注-v编译时显示包名-p n开启并发编译,默认情况下为CPU核数-a强制重新构建所有的文件-n打印编译时会用的所有命令,但不真正执行-x打印编译时会用到的所有命令-race开启竞态检测,支持linux/amd64,freebsd/amd64,darwin/amd64,windows/amd64-work打印临时工作目录的名称-o指定输出文件-tags构建出带tag的版本原创 2021-10-29 17:45:13 · 1775 阅读 · 0 评论 -
docker Ubuntu安装
ubuntu docker 安装手动安装卸载旧版本 sudo apt-get remove docker docker-engine docker.io containerd runc设置仓库更新apt包索引sudo apt-get update安装apt依赖包sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ softwar原创 2021-05-20 19:25:16 · 182 阅读 · 0 评论 -
chan和goroutine泄露
go chanchan 类型<发送/写>型 chan<-<接收/读>型 <-chan双向型 chanchan 操作构造/初始化 make()关闭 close()判等 ==<发送/写>数据 chan <- send_data<接收/读>数据 recv_data := <- chanchan 关闭或有数据,读操作不阻塞chan 未关闭且无数据,读操作阻塞package mainimport "fmt"原创 2021-05-19 00:03:05 · 406 阅读 · 1 评论 -
go panic和recover
在golang当中不存在tye … catch 异常处理逻辑。在golang当中使用defer, panic和recover来控制程序执行流程,借此来达到处理异常的目的。PanicPanic是一个可以停止程序执行流程的内置函数。 假设当前F函数当中某处代码触发panic函数,则F函数停止后面代码的执行,转而执行F函数内部的defer函数(如果已经声明了defer函数的话…),然后结束F函数,将当前处理权转给F的调用函数。对于F的调用方M来说,F是调用panic函数结束的,而不是执行return结.原创 2021-05-16 00:27:28 · 367 阅读 · 0 评论 -
go defer
延迟调用defer可以理解为作用域内的局部变量的析构,即RAII思想。因此defer语句经常使用于成对的操作,例如打开和关闭,加锁与解锁,连接和断开等你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回没有defer时对于文件的操作func ReadWrite(filepath string) bool { f, err := os.Open(filepath) if err != nil { fmt.Pri原创 2021-05-16 00:24:07 · 115 阅读 · 0 评论 -
go grpc的简单使用
(Linux)前提需要安装protobufsudo apt install golang-goprotobuf-devsudo apt-get install protobuf-compiler安装protoc-gen-gosudo apt install protoc-gen-go目录结构我这边是编写了一个登录的服务,目录结构如下图所示,使用go mod来管理依赖,go mod开启的话需要设置环境变量go env GO111MODULE=on,然后输入go mod init pa原创 2021-05-16 00:18:15 · 381 阅读 · 0 评论