Golang云原生
文章平均质量分 93
简说Linux
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
初学者入门|一文带你读懂Kubernetes
其通过一个软件层的封装,提供和物理硬件相同的输入输出表现,实现了操作系统和计算机硬件的解耦,将OS和计算机从一对一转变为多对多(实际上是一对多)的关系。Pod的实现需要使用一个中间容器(Infra容器),在这个Pod中,Infra容器永远是第一个被创建的容器,用户定义的其他容器通过Join Network Namespace的方式与Infra容器关联在一起。对于声明式而言,用户设定目标为3,系统获取当前副本数为2,系统判定当前值与目标值的差为1,便自行加1,最终实现副本数为3的目标状态。原创 2022-12-23 20:52:57 · 392 阅读 · 0 评论 -
从架构层面了解Kubernetes
在K8s中控制面还有很多核心过程,但因为篇幅所限这里无法讨论所有的控制面板过程。架构设计过程:整体架构->核心流程设计。这里整理K8s架构的时候也是以类似的方式进行。K8s是由开源社区维护的,那随着不断的演进肯定会朝着好的方向前进。但在发展过程中,代码的水平设计的水平都会出现参差不齐的情况。在K8s中有好的有不好的,我们只需要取其精华,去其糟粕即可。原创 2022-12-23 20:48:01 · 688 阅读 · 0 评论 -
Docker常用命令的原理与简单实战
docker export命令创建一个tar文件,并且移除了元数据和不必要的层,将多个层整合成了一个层,只保存了当前统一视角看到的内容(译者注:expoxt后的容器再import到Docker中,通过docker images –tree命令只能看到一个镜像;docker stop和docker kill命令会发送UNIX的信号给运行中的进程,docker pause命令则不一样,它利用了cgroups的特性将运行中的进程空间暂停。和export命令不同,这个命令为每一个层都保存了它们的元数据。原创 2022-11-23 21:11:47 · 305 阅读 · 0 评论 -
Golang简洁架构实战
以上就是我对 golang 的项目中发现问题的一点点总结与思考,思考的先不管对不对,总归是解决了我们当下的一些问题。不过,项目总归是需要不断重构完善的,所以下次有问题的时候下次再改呗。对于我上面的总结和描述感觉有不对的地方,请随时指出来一起讨论。原创 2022-11-23 20:55:48 · 1267 阅读 · 0 评论 -
从Clickhouse 到 Snowflake: 云原生
Clickhouse的功能迭代速度是很快的,比如最近社区推出的LLVM表达式优化、异步的Pipeline执行、zOrder等,都是非常重要的feature,对性能提升十分明显,一旦分叉这些功能就都用不上了,所以我们坚信兼容Clickhouse社区虽然会慢点,我们的设计会复杂点,但是会走的更远。Master Node自身多副本,多副本之间通过一致性协议保证高可用。模块结构如上图所示,在我们的架构中,Clickhouse实际是一个单机的库,所以虽然我们实现了复杂的控制流和存算分离的功能,但是通过精巧的设计,原创 2022-11-19 22:00:00 · 910 阅读 · 0 评论 -
小白入门|从Docker到Kubernetes
Docker 是一个开源的应用容器引擎,是一种资源虚拟化技术,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。虚拟化技术演历路径可分为三个时代:1. 物理机时代,多个应用程序可能跑在一台物理机器上2. 虚拟机时代,一台物理机器启动多个虚拟机实例,一个虚拟机跑多个应用程序3. 容器化时代,一台物理机上启动多个容器实例,一个容器跑多个应用程序在没有 Docker 的时代,我们会使用硬件虚拟化(虚拟机)以提供隔离。原创 2022-11-19 17:44:09 · 556 阅读 · 0 评论 -
Golang单元测试指引
在编写桩模块时会发现,模块之间的调用关系在工程规模并不大的本案例中,也依然比较复杂,需要开发相应桩函数,代码量会增加许多,也会消耗一些开发人员的时间,因此反推到之前流程的开发实践中,可以得出结论就是提高模块的内聚度可简化单元测试,如果每个模块只能完成一个,所需测试用例数目将显著减少,模块中的错误也更容易发现。因此还是需要倒推到开发模块之前,就要设计更好的结构,在开发的过程中遵循相应的规则,通过测试先行的思想,使开发的工程具有更好的可测试性。但在测试框架的选择上,我们更推荐 GoConvey。原创 2022-11-18 15:52:56 · 841 阅读 · 0 评论 -
学Golang,看这一篇
1:使用多返回值,错误码来判断程序的处理;一个 buffer 会阻塞其它协程的 写, N 个协程创建 N 个 Buffer, 就是非阻塞的了。1:通过 struct tag 来解析,相对比较简单,有点类似那个万能程序;实现一个 接口的经典例子【golang 的类组织方式,采用的是。也可调用 对应的API,对某个函数 精准的输出 prof 文件。, 一次只能放入一个值, 在 值 被取走前, 通道是阻塞的。1: 对象池中如果需要放入任意的数据类型,就放入。2:行为的方法实现,决定了最终传入的实例是什么。原创 2022-11-18 14:01:54 · 510 阅读 · 0 评论 -
Go runtime剖析系列(一):内存管理
nil,更新 gcAssist 相关数据,略过 7. 检查是否需要启动新一轮 gc,略过 下面我们分别分析微对象,小对象,大对象的内存分配。程序在运行过程中会不断的调用分配器分配堆内存,同时也会通过赋值器更新内存数据,如果我们将内存看做为一个个小的对象集合,那程序的运行其实就是更改这个对象图,其中分配器在这个对象图中创建节点,赋值器更改节点之间的依赖关系,当我们从根节点(全局对象,栈对象)出发遍历对象图时,没有被遍历到的节点就会成为垃圾,等待 gc 的回收。原创 2022-11-17 17:05:04 · 806 阅读 · 0 评论 -
Kubernetes 入门&进阶实战
再打个形象的比喻,在同一个 Pod 里的几个 Docker 服务/程序,好像被部署在同一台机器上,可以通过 localhost 互相访问,并且可以共用 Pod 里的存储资源(这里是指 Docker 可以挂载 Pod 内的数据卷,数据卷的概念,后文会详细讲述,暂时理解为“需要手动 mount 的磁盘”)。到这里,相信你已经对 K8S 究竟是做什么的,有了大概认识。笔者一边写文章,一边查阅和整理 K8S 资料,过程中越发感觉 K8S 架构的完备、设计的精妙,是值得深入研究的,K8S 大受欢迎是有道理的。原创 2022-11-17 16:55:59 · 625 阅读 · 0 评论 -
从 bug 中学习:六大开源项目告诉你 go 并发编程的那些坑
并发编程中,go不仅仅支持传统的通过共享内存的方式来通信,更推崇通过channel来传递消息,这种新的并发编程模型会出现不同于以往的bug。别往坑里跳,编程更美妙。第二行中的匿名函数形成了一个闭包(closures),在闭包内部可以访问定义在外面的变量,如上面的例子中,第 1 行在写 i 这个变量,在第 3 行在读 i 这个变量。上面的代码中第一个 case 分支 timeout 有可能是个 nil 的 channel,select 在 nil 的 channel 上,这个分支不会被触发,因此不会有问题。原创 2022-11-17 16:51:38 · 180 阅读 · 0 评论 -
两万字长文带你深入Go语言GC源码
为了防止丢失从灰色对象到白色对象的路径,应该假设 *slot 可能会变为黑色, 为了确保 ptr 不会在被赋值到 *slot 前变为白色,shade(*slot) 会先将 *slot 标记为灰色, 进而该写操作总是创造了一条灰色到灰色或者灰色到白色对象的路径,这样删除写屏障就可以保证弱三色不变性,老对象引用的下游对象一定可以被灰色对象引用。Go 在重新扫描的时候必须保证对象的引用不会改变,因此会进行暂停程序(STW)、将所有栈对象标记为灰色并重新扫描,这通常会消耗10~100 毫秒的时间。原创 2022-11-17 16:09:07 · 972 阅读 · 0 评论 -
一文教你搞懂Go中栈操作
在 32 位模式下,它总是 4GB 内存地址空间,内存分配是分配虚拟内存给进程,当进程真正访问某一虚拟内存地址时,操作系统通过触发缺页中断,在物理内存上分配一段相应的空间再与之建立映射关系,这样进程访问的虚拟内存地址,会被自动转换变成有效物理内存地址,便可以进行数据的存储与访问了。会发生在 GC 的时候。当执行栈扩容时,会在内存空间中分配更大的栈内存空间,然后将旧栈中的所有内容复制到新栈中,并修改指向旧栈对应变量的指针重新指向新栈,最后销毁并回收旧栈的内存空间,从而实现栈的动态扩容。原创 2022-11-16 16:34:11 · 1300 阅读 · 1 评论 -
Go程序内存泄露问题快速定位
使用 gcore 转储整个进程,原理类似,gcore 会在转储完后立即 detach 进程,比手动 dump 速度快,对 traced 进程的影响时间短,但是转储文件一般比较大(记得 ulimit -c 设置下),core 文件使用 hexdump 分析的时候也可以选择性跳过一些字节,以分析感兴趣的可疑内存区。或者,是有连续的大内存区块,也是待分析的可疑对象,或者这样的内存区块数量比较多,也应该作为可疑的分析对象。不管如何发现的,明确存在这一问题之后,就需要及时选择合适的方法定位到问题的根源,并及时修复。原创 2022-11-16 16:14:07 · 3107 阅读 · 0 评论 -
go pprof 实战
但是实际情况是,如果使用了 map 作为池,pool 的老 map 数据还需要清理,这里简单做了 benchmark,这里的测试方法是,pool 每次申请 2000 大小的 map[int]int,然后做一些简单操作后重新 put 进入 pool 中。可以发现确实内存一直增长,但是对于此场景是在有请求时发现内存不断上涨,但是请求下降后内存会逐步恢复,说明当前系统虽然没有内存泄露,但是确实存在内存瓶颈,在当前 qps 下,业务处理后的内存释放跟不上内存申请的速度,最终会导致 OOM。(然后发现了很多问题)原创 2022-11-16 16:03:08 · 671 阅读 · 0 评论 -
教你打造高性能的 Go 缓存库
我在看一些优秀的开源库的时候看到一个有意思的缓存库 fastcache,在它的介绍主要有以下几点特点:本文会通过模仿它写一个简单的缓存库,从而研究其内核是如何实现这样的目标的。希望各位能有所收获。在项目中,我们经常会用到 Go 缓存库比如说 库。但很多缓存库其实都是用一个简单的 Map 来存放数据,这些库在使用的时候,当并发低,数据量少的时候是没有问题的,但是在数据量比较大并发比较高的时候会延长 GC 时间,增加内存分配次数。比如,我们使用一个简单的例子:在这个例子中,预分配了大小是 的 map,然后原创 2022-11-16 15:46:56 · 786 阅读 · 0 评论 -
腾讯代码安全指南开源,涉及 C/C++、Go 等六门编程语言
腾讯代码安全指南旨在梳理 API 层面的风险点并提供详实可操作的编码指引,是我们开展 DevSecOps 安全左移实践探索过程中,梳理沉淀面向开发人员的代码安全参考材料。本次开源涉及 C/C++、JavaScript、Node、Go、Java、Python 六门编程语言的安全指南。近年来,无论是 DevSecOps,还是 Google SRE 的可靠和安全性理念,都提倡“安全需要每个工程师的参与”。其中涉及的“安全左移”理念也再次被推向前台,获得关注。原创 2022-11-16 15:43:25 · 1655 阅读 · 0 评论 -
Go语言中的零拷贝优化,值得大家收藏
由于最初的 mutex 是一种完全内核态的互斥量实现,在并发量大的情况下会产生大量的系统调用和上下文切换的开销,在 Linux kernel 2.6.x 之后都是使用 futex (Fast Userspace Mutexes) 实现,也即是一种用户态和内核态混用的实现,通过在用户态共享一段内存,并利用原子操作读取和修改信号量,在没有竞争的时候只需检查这个用户态的信号量而无需陷入内核,信号量存储在进程内的私有内存则是线程锁,存储在通过。很多顶级的 Go 开源库都会重度使用。原创 2022-11-14 21:07:49 · 1714 阅读 · 0 评论 -
带你全景俯瞰云原生与 kubernetes
按字面意思的理解,云原生应用是指在云上生长出来的应用,云上的“原住民”。业界还有阿里的 ACK,腾讯的 TKE,华为的 CCE 等竞品。有个说法很形象:K8S 只是一套毛坯样板,而像 GKE 这样的平台则相当于房地产商,开发并出售一套套精装修的商品房,让你可以拎包入住。同一个 Pod 内的容器共享同一个 IPC 命名空间,它们可以使用标准的进程间通信方式来互相通信,比如“SystemV 信号量”与“POSIX 共享内存”。身处技术变革浪潮的后台同学,应该都深切地感受到了云原生技术在公司内外的蓬勃发展。原创 2022-11-14 21:05:21 · 832 阅读 · 0 评论 -
gRPC 基础概念详解
(gRPC Remote Procedure Calls) 是 Google 发起的一个开源远程过程调用系统,该系统基于 HTTP/2 协议传输,本文介绍 gRPC 的基础概念,首先通过关系图直观展示这些基础概念之间关联,介绍异步 gRPC 的 Server 和 Client 的逻辑;不会,因为每个 RPC 对应的函数名是不同。以下 CallData 并非 gRPC 中的概念,而是异步 Server 在实现过程中为了方便进行的封装,其中的 Status 也是在异步调用过程中自定义的、用于转移的状态。原创 2022-11-14 20:37:08 · 2174 阅读 · 0 评论 -
一文快速了解Docker和Kubernetes
Docker 是一个开源的应用容器引擎,是一种资源虚拟化技术,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。虚拟化技术演历路径可分为三个时代:在没有 Docker 的时代,我们会使用硬件虚拟化(虚拟机)以提供隔离。这里,虚拟机通过在操作系统上建立了一个中间虚拟软件层 Hypervisor ,并利用物理机器的资源虚拟出多个虚拟硬件环境来共享宿主机的资源,其中的应用运行在虚拟机内核上。但是,虚拟机对硬件的利用率存在瓶颈,因为虚拟机很难根据当前业务量动态调整其原创 2022-11-14 20:35:17 · 1169 阅读 · 0 评论 -
Go 语言中各式各样的优化手段
我们 CI 是用蓝盾流水线实现的,有一次业务反馈说蓝盾编译的二进制会比自己开发机编译的体积大 50%左右。这也是两个比较常规的优化手段,核心还是复用对象,减少内存分配。使用时要注意 go 版本更新后,是否有兼容问题,毕竟 go 团队并没有保证这些未导出的方法变量后续不会变更。和函数信息的,我们可以把第一次的结果缓存起来,后面直接使用。对网络 io,以及定时器的管理,会放到自己维护的一个 epoll 里,具体可以参考。压测数据如下,优化后稍微减轻这部分的负担,同时消除掉不必要的内存分配。原创 2022-11-14 17:32:51 · 508 阅读 · 0 评论 -
Go怎么优雅地传递、返回、暴露错误,同时便于回溯翻查的解决方案
此外,笔者需要再强调的是:在开发中,针对各种不同的、正式的错误用例依然需要完整覆盖,尽可能通过已有的 code - message 机制将足够清晰的信息告知主调方。在笔者的经验中,我们在使用 code - message 机制的时候,特别是业务初期,难以避免的是前后端的设计文案没能完整地覆盖所有的错误用例,或者是错误极其罕见。方面,笔者其实没有特别好的方法来模拟,即便是上面的方法也有一个很让人头疼的问题:defer 写法导致错误处理前置,而正常逻辑后置了,从可读性的角度来说非常不友好。原创 2022-11-12 16:31:21 · 339 阅读 · 0 评论 -
Golang 编程思维和工程实战
在我们的工程中,抽象出一种我自认为是类似 MVC 的模型,但是不完全一样,个人觉得这个模型抽象的比较好,容易扩展,模块清晰。singleton.NewSingleton 就是具体单例模式的实现,然后赋值给 SingleService,这样,在程序中任何需要获取这个对象的时候,就直接通过 SingleService 来调用,这个调用,系统会保证,里面的 singleMsgProxy 只会被初始化对象一次,这个 singleMsgProxy 就是 new 了一个对象,并且这个对象是只需要被初始化一次的。原创 2022-11-11 21:51:24 · 237 阅读 · 0 评论 -
Go语言编写设计模式
【代码】Go语言编写设计模式。原创 2022-11-11 17:37:11 · 547 阅读 · 0 评论 -
自己动手写一个Golang ORM框架
特别在 1 个全新的项目中,我们都会用一个 ORM 框架去连接数据库,而不是直接用原生代码去写 SQL 链接,原因有很多,有安全考虑,有性能考虑,但是,更多的我觉得还是懒(逃)和开发效率低,因为有时候一些 SQL 写起来也是很复杂很累的,特别是查询列表的时候,又是分页,又是结果集,还需要自己。再看多条的查询,第一步,得先把查询的数据结构先定义出来,再实例化 1 个多维的数组,再通过 for 循环去给这个数组赋值,值得注意的是这个数据结构的字段数得和 select 出来的字段数保持一致,不然就会丢失。原创 2022-11-11 17:01:51 · 895 阅读 · 0 评论 -
从Clickhouse 到 Snowflake(二): MPP 查询层
用户可以在新场景里使用 MPP 查询引擎,逐步的把 Clickhouse 目前的查询语法废弃,平滑的升级到新的查询引擎,未来我们也会在 MPP 查询引擎中兼容 Clickhouse 的 SQL 语法标准,让用户的迁移更便利。在具备通用的 MPP 执行框架之后,已经可以跑通 Join 等大多数复杂查询,后续通过查询优化器合理的查询规划,可以进一步提升复杂查询的性能,基于代价的查询优化器(CBO)正在研发中,预计下一个版本发布。这个查询语句被规划为 3 个阶段, 扫描数据, 聚合计算,返回结果;原创 2022-11-10 13:52:16 · 618 阅读 · 0 评论 -
从 Clickhouse 到 Snowflake(一): 云原生
在存算分离模式下,多副本的目标已经从保证数据的可靠性转变为保证服务的可用性,通过把每个副本本地的状态消除,可以任意增加副本的数目,提升服务的可用性而不需要付出存储成本;模块结构如上图所示,在我们的架构中,Clickhouse 实际是一个单机的库,所以虽然我们实现了复杂的控制流和存算分离的功能,但是通过精巧的设计,基本上对 Clickhouse 没有侵入,改动了极少的代码,这使得后续的版本升级更加方便,能够随时合并 Clickhouse 社区的最新功能。原创 2022-11-09 15:08:25 · 1345 阅读 · 0 评论 -
Golang 并发编程指南
简单调度图如上,有关于 P 再多个 M 中切换,公共 goroutine 队列,M 从线程缓存中创建等步骤没有体现,复杂过程可以参考文章简单了解。我们可以再每个 CPU 上进行循环无关的迭代计算,我们仅需要创建完所有的 goroutine 后,从 channel 中读取结束信号进行计数即可。这东西可以并发读,不可以并发读写/并发写写,不过现在即便场景是读多写少也很少用到这,一般集群环境都得分布式锁了。关系如图,灰色的 G 则是暂时还未运行的,处于就绪态,等待被调度,这个队列被 P 维护。原创 2022-11-09 14:59:42 · 1104 阅读 · 0 评论 -
云原生背景运维转型之SRE实践
重点介绍了云原生背景下运维转型的思考,围绕着整个 DevOps 交付链,贴近业务不断输出运维的能力与价值。这篇内容我想谈谈 DevOps 的下半段,通过我们的构建服务稳定性保障实践,利用 SRE 的思想与方法,不断去冲刺稳定性的终极目标: “提升 MTBF(平均故障时间间隔)、降低 MTTR(故障平均修复时间)”,很多小伙伴会有疑问,DevOps 与 SRE 到底是什么样的关系?在 Google 出版的第二本书《The Site Reliability Workbook》的第一章节 ,已经明确给出了这个问题原创 2022-11-09 14:28:30 · 1355 阅读 · 0 评论 -
Go语言与并发编程
并发编程,可以说一直都是开发者们关注最多的主题之一。而 Golang 作为一个出道就自带“高并发”光环的编程语言,其并发编程的实现原理肯定是值得我们深入探究的。Go 并发编程模型在底层是由操作系统所提供的线程库支撑的,这里先简要介绍一下线程实现模型的相关概念。线程的实现模型主要有 3 个,分别是:用户级线程模型、内核级线程模型和两级线程模型。它们之间最大的差异在于用户线程与内核调度实体(KSE)之间的对应关系上。内核调度实体就是可以被操作系统内核调度器调度的对象,也称为内核级线程,是操作系统内核的最小调度单原创 2022-11-06 22:32:35 · 219 阅读 · 0 评论 -
Go云原生高性能编程技法,值得观看
在 Linux 系统中,标准输出也可以视为文件,内核(Kernel)利用文件描述符(File Descriptor)来访问文件,标准输出的文件描述符为 1,错误输出文件描述符为 2,标准输入的文件描述符为 0。频繁地分配、回收内存会给 GC 带来一定的负担,严重的时候会引起 CPU 的毛刺,而 sync.Pool 可以将暂时不用的对象缓存起来,待下次需要的时候直接使用,不用再次经过内存分配,复用对象的内存,减轻 GC 的压力,提升系统的性能。可以预见的是,随着分片粒度地变小,性能差距会越来越大。原创 2022-11-06 22:17:48 · 939 阅读 · 0 评论 -
Golang 本地缓存选型对比及原理总结
我们一般做缓存就是为了能提高系统的读写性能,缓存的命中率越高,也就意味着缓存的效果越好。fastcache 一方面充分利用了分片来降低锁的粒度,另一方面在索引存储时采用了对 map 的优化,同时在分配内存时,直接从堆外申请内存,自己实现了分配和释放内存的逻辑。此外二者均无法支持数据的过期和淘汰,同时在存储大量数据时,又会产生比较频繁的 GC 问题,更严重的情况下导致线上服务无法稳定运行。同时 bigcache 中数据的过期是通过全局的时间窗口维护的,每个单独的 kv 无法设置不同的过期时间。原创 2022-11-05 15:24:30 · 1984 阅读 · 0 评论 -
Go 组件:context 学习笔记
虽然我们平时写代码时直接 context.Context 拿来就用,但实际上 context.Context 是一个接口,源码里是有多种不同的实现的,借此实现不同的功能。这个接口约定了可以取消的 context,比如 cancelCtx 和 timerCtx 是可以取消的,emptyCtx 和 valueCtx 是不可以取消的。Context 顾名思义是协程的上下文,主要用于跟踪协程的状态,可以做一些简单的协程控制,也能记录一些协程信息。有并发的地方就有江湖。调用的次数多了,生成的子树就很庞大。原创 2022-11-04 17:30:41 · 1136 阅读 · 0 评论
分享