Code For Colorful Life
golang channel底层实现
本文内容基于go1.13.1源码。
从 golang 官方文档https://golang.org/ref/spec#Channel_types可以了解到 channel 数据类型所支持的操作,接下来我将尝试探索这些操作底层是如何实现的:
- channel 底层数据结构的实现?
- channel 是如何创建、发送、接收的?
- 只能发送(chan<- int))和只能接收(<-chan int)的 channel 是如何实现的?
- select 是怎么实现同时监听多个 channel 的?
Read more...
golang slice底层实现
本文内容基于go1.13.1源码。
通过make
给局部变量分配空间时,如果空间较少,则会直接在栈上分配 slice 的 header 和 数组,否则会调用runtime.makeslice
。
slice 结构:
type SliceHeader struct {
Data uintptr // 指向连续内存数组
Len int
Cap int
}
Read more...
golang map底层实现
本文学习参考自:map
本文内容基于go1.13.1源码。
在阅读Go map的实现代码时,最好先了解哈希表这种数据结构实现的算法思想,对理解Go map的实现会有帮助,我这里简单总结下:
- map 内部采用的是数组存储 KV,每个数组元素可以认为是一个桶
- key 经过哈希算法后再与 map的数组长度取模映射到某个桶中
- 如果多个 key 映射到了相同的桶,就意味着出现了哈希冲突,解决冲突的方式有两种:开放寻址法和链表法
- 当 KV 过多时,map 就需要扩容(因为数组是固定大小的),扩容的策略是新分配一个更大的数组,然后在插入和删除 key 的时候,将对应的桶的数据搬移到新分配的数组的桶中。这种方式把扩容所需要的 O(n) 时间开销均摊到了 O(1) 的插入和删除操作中。
- map 中用装载因子(map中元素的个数 / map的容量)来表示空闲位置的情况。装载因子越大,说明空闲位置越少,冲突越多。
Read more...
golang 汇编学习小结
本文学习参考自:plan9 assembly 完全解析 和 Go汇编语言
寄存器
Go 汇编的4个伪寄存器,手写Go 汇编的时候使用:
- FP:用于引用参数和返回值
- PC:程序计数器
- SB:用于引用全局符号
- SP:指向当前栈帧的BP,引用局部变量
Read more...
Golang中使用断路器
本文学习参考自:Circuit Breaker pattern 和 cep21/circuit
业务问题场景
在业务系统中,通常存在服务之间的相互调用,例如服务A调用服务B,当出现如下情形:
- 服务A与服务B之间的网络出现异常
- 服务B过载
- 服务B出现异常
服务A应该减少对服务B的调用量,甚至服务A应该停止调用服务B,有必要的话,还可以采取相应的降级措施`。当服务B恢复正常后,才开始继续调用服务B。
Read more...
容器网络
本文学习总结自极客时间 深入剖析Kubernetes。
单宿主机容器网络互通
容器通过Veth Pair连接到docker0网桥上,实现了容器与容器之间,容器与宿主机之间的网络互通。
- Veth: virtual Ethernet devices
- Veth Pair: 一对虚拟以太网设备,可以看作现实生活中的网线,能在不同namespace下传输流量
YouTube视频:Linux VETH Pair - Virtual Ethernet Pair
2个容器之间直接通过Veth Pair可以实现网络互通,但如果有n个容器之间需要互通的话,就可能需要创建n(n-1)/2个Veth Pair,就跟现实生活中需要把很多台计算机实现网络互通一样。
在现实生活中,通常是采用网桥,只需要将每台计算机通过一根网线连接在网桥上,那么计算机之间就可以实现网络互通了。
所以可以通过在操作系统上虚拟出一个网桥设备,将容器通过Veth Pair连接到网桥上,实现容器之间网络互通。
YouTube视频:Docker Advanced Networking
使用bridge网络的容器,路由表类似这样子:
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
对于172.17.0.0/16网段的路由是一条直连规则,凡是匹配到这条规则的IP包,应该经过eth0网卡,通过二层网络直接发往目的主机,因为当前主机和目的主机连接在同一个网桥上。而对于其他IP包,则需要发给网关,网关会根据自己的路由信息对数据包进行转发。
Read more...
认识docker
本文学习总结自极客时间 深入剖析Kubernetes。
进程:程序运起来后的计算机执行环境的总和。
容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。
Cgroups 技术是用来制造约束的主要手段,而Namespaces 技术则是用来修改进程视图的主要方法。
Read more...