July 31, 2021
在linux下安装Kubernetes
"环境 ubuntu18.04 64位\nKubernetes v1.21.3\n这里需要注意,本教程安装的k8s版本号 \u0026lt;- v1.24.0,主要是因为从v1.24.0以后移除了 Dockershim,无法继续使用 Docker Engine,后续将默认采用 containerd ,它是一个从 CNCF 毕业的项目。如果仍想使用原来 Docker Engine 的方式可以安装 cri-dockerd ,它是 Dockershim 的替代品。\n如果你想将现在 Docker Engine 的容器更换为 containerd,可以参考官方迁移教程 将节点上的容器运行时从 Docker Engine 改为 containerd\n为了解决国内访问一些国外网站慢的问题,本文使用了国内阿里云的镜像。\n更换apt包源 这里使用aliyun镜像 , 为了安全起见,建议备份原来系统默认的 /etc/apt/sources.list 文件\n编辑文件 /etc/apt/sources.list,将默认网址 或 替换为\n更新缓存\n$ sudo apt-get clean all $ sudo apt-get …"
June 27, 2021
SPIFFE 学习参考资料
"The SPIFFE Workload API\nEnvoy spiffe spire\n简而言之SPIFFE\nSPIFFE信任域\n使用SPIRE(自动)提供TLS证书给Envoy以进行更强大的身份验证\n谁使用SPIFFE?\nSecuring the Service Mesh with SPIRE 0.3"
May 23, 2021
Golang中的runtime.LockOSThread 和 runtime.UnlockOSThread
"在runtime中有 [runtime.LockOSThread](https://github.com/golang/go/blob/go1.16.3/src/runtime/proc.go#L4248-L4278) 和 [runtime.UnlockOSThread](https://github.com/golang/go/blob/go1.16.3/src/runtime/proc.go#L4302-L4323) 两个函数,这两个函数有什么作用呢?我们看一下标准库中对它们的解释。\nruntime.LockOSThread // LockOSThread wires the calling goroutine to its current operating system thread. // The calling goroutine will always execute in that thread, // and no other goroutine will execute in it, // until the calling goroutine has made …"
May 21, 2021
认识无锁队列
"无锁队列是 lock-free 中最基本的数据结构,一般应用在需要一款高性能队列的场景下。\n对于多线程用户来说,无锁队列的入队和出队操作是线程安全的,不用再加锁控制\n什么是无锁队列 队列每个开发者都知道,那么什么又是无锁队列呢?字面理解起来就是一个无锁状态的队列,多个线程(消费者)同时操作数据的时候不需要加锁,因为加/解锁都是一个很消耗资源的动作。\n实现原理 我们先看一下无锁队列的底层实现数据结构。\n数据结构 无锁队列底层的数据结构实现方式主要有两种:数组 和 链接。\n数组 在首次初始化时,需要申请一块连接的大的内存。读写数据直接从数据的指定位置操作即可,时间复杂度为O(1)。\n缺点:数组长度有限,一旦数组索引位置写满,则无法继续写入,即队列有上限。\n链表 不用像数组一样,刚开始就申请一块连接的大的内存空间。只有在每次写时数据的时候,申请这个数据节点大小的内存即可,这样就可以实现无限的写入,没有长度限制问题。\n缺点:每次写数据都要申请内存,在写的场景,最差的情况是多少个数据就申请多少次内存,而每次申请都是一个消耗资源的动作。\n可以看到无锁底层的实现的不同各有优势。多数据情况下,我们都采 …"
May 10, 2021
Runtime: goroutine的暂停和恢复源码剖析
"上一节《 GC 对根对象扫描实现的源码分析》中,我们提到过在GC的时候,在对一些goroutine 栈进行扫描时,会在其扫描前触发 G 的暂停([suspendG](https://github.com/golang/go/blob/go1.16.2/src/runtime/preempt.go#L76-L254))和恢复([resumeG](https://github.com/golang/go/blob/go1.16.2/src/runtime/preempt.go#L256-L280))。\n// markroot scans the i\u0026#39;th root. // // Preemption must be disabled (because this uses a gcWork). // // nowritebarrier is only advisory here. // //go:nowritebarrier func markroot(gcw *gcWork, i uint32) { baseFlushCache := uint32(fixedRootCount) …"
May 7, 2021
goroutine栈的申请与释放
"对于提高对 stack 的使用效率,避免重复从heap中分配与释放,对其使用了 pool 的概念,runtime 里为共提供了两个pool, 分别为 stackpool ,另一个为 stackLarge。stack pool\nstackpool: 16b~32k 对应通用的大小的stack。获取时通过调用 stackpoolalloc(), 释放时调用 stackpoolfree()。\nstackLarge:对应 \u0026gt; 32K 的 stack\n在程序全局调度器 初始化 时会通过调用 stackinit() 实现对 stack 初始化。\n当我们执行一个 go func() 语句的时候,runtime 会通过调用 newproc() 函数来创建G。而内部真正创建G的函数为 [newproc1()](https://github.com/golang/go/blob/go1.16.3/src/runtime/proc.go#L3990-L4098),在没有G可以复用的情况下,会通过 newg = malg(_StackMin) 语句创建一个包含stack的G。\n// Allocate a …"
May 7, 2021
Golang的GPM 模型在网络编程中存在的问题
"现状 目前在网络编程中,golang采用的是一种 goroutine-per-connection 的模式,即为每一个连接都分配一个goroutine,一个连接就是一个goroutine,多个连接之间没有关系。\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;io/ioutil\u0026#34; \u0026#34;net\u0026#34; \u0026#34;time\u0026#34; ) //模拟server端 func main() { tcpServer, _ := net.ResolveTCPAddr(\u0026#34;tcp4\u0026#34;, \u0026#34;:8080\u0026#34;) listener, _ := net.ListenTCP(\u0026#34;tcp\u0026#34;, tcpServer) for { //当有新客户端请求时拿到与客户端的连接 conn, err := listener.Accept() if err != nil { fmt.Println(err) continue } // 处理逻辑 goroutine-per-connection go handle(conn) } } …"
May 1, 2021
Linux 内核select、poll 和 eventpoll 的实现
"Linux 内核仓库 https://github.com/torvalds/linux\nLinux 内核文档: https://www.kernel.org/doc/html/latest/index.html( 中文)\n开发工具参考: https://www.kernel.org/doc/html/latest/dev-tools/index.html\n也可以使用 VSCode + 插件C/C++ GNU Global\n通过前面三个博客可以得知 select,** poll, eventpoll** 的详细实现,现在来总结对比下它们之间的不同:\nselect 流程图 poll 流程图 eventpoll 流程图 优缺点总结 \u0026lt;1\u0026gt; 监控文件最大数不同:select和poll都是以数组形式传入药监控的文件句柄,而这个数组是有大小限制的1024个左右(不是很清楚).而epoll则是每add一个文件句柄会new一个新epi出来,挂载在ep的红黑树中,监控的文件个数没有明确限制(可能会受限于系统最大打开文件句柄数)从这点上看,epoll是优于select和poll. …"
April 30, 2021
缓存池 bytebufferpool 库实现原理
"上一节 《Runtime: Golang 之 sync.Pool 源码分析》 我们介绍了sync.Pool 的源码分析,本节介绍一个 fasthttp 中引用的一缓存池库 [bytebufferpool](https://github.com/valyala/bytebufferpool),这两个库是同一个开发者。对于这个缓存池库与同类型的几个库的对比,可以参考 https://omgnull.github.io/go-benchmark/buffer/。\n建议大家了解一下[fasthttp](https://github.com/valyala/fasthttp) 这个库,性能要比直接使用内置的 net/http 高出很多,其主要原因是大量的用到了缓存池 sync.Pool 进行性能提升。\n用法 // https://github.com/valyala/bytebufferpool/blob/18533face0/bytebuffer_example_test.go package bytebufferpool_test import ( \u0026#34;fmt\u0026#34; …"
April 29, 2021
初识kubernetes 组件
"对于一个刚刚接触 kubernetes(k8s)的新手来说,想好更好的学习它,首先就要对它有一个大概的认知,所以本文我们先以全局观来介绍一个 kubernetes。\nkubernetes 架构 kubernetes 架构图 kubernets 整体可以分为两大部分,分别为 Master 和 Node ,我们一般称其为节点,这两种角色分别对应着控制节点和计算节点,根据我们的经验可以清楚的知道 Master 是控制节点。\nMaster 节点 控制节点 Master 节点由三部分组成,分别为 Controller Manager 、 API Server 和 Scheduler ,它们相互紧密协作,每个部分负责不同的工作职责。\ncontroller-manager 全称为 kube-controler-manager 组件,主要用来负责容器编排。如一个容器(实际上是 pod,pod 是最基本的调度单元。一般一个 pod 里会部署一个容器服务)服务可以指定副本数量,如果实际运行的副本数据与期望的不一致,则会自动再启动几个容器副本,最终实现期望的数量。这个组件,就是一系列控制器的集合。我们可以查 …"