网管叨bi叨

其他

Go学设计模式--怕把核心代码改乱,记得用代理模式

需要实现一个代表驾驶行为的接口(interface)Vehicle,该接口只有一个方法Drive()。"本文使用的完整可运行源码去公众号「网管叨bi叨」发送【设计模式】即可领取"type
2022年12月26日
其他

K8s 长什么样?一文道清它的整体架构

)是一个基于容器技术的分布式架构方案,它源自Google内部大规模集群管理系统——Borg,自2015年开源后得到开源社群的全力支援,IBM、惠普、微软、RedHat等业界巨头纷纷加入,成为后来的
2022年6月6日
其他

从Go log库到Zap,怎么打造出好用又实用的Logger

日志无论对于程序还是程序员都非常重要,有多重要呢,想要长期在公司健健康康的干下去就得学会阶段性划水,阶段性划水的一大关键的就是干活快过预期但是装作。。。不对,这个开头不对劲,下面重来。日志无论对于程序还是程序员都非常重要,程序员解决问题的快慢除了经验外,就是看日志能不能有效地记录问题发生的现场以及上下文等等。那么让让程序记录有效的日志,除了程序内记日志的点位尽量精准外,还需要有一个称手的
2022年5月31日
其他

解惑篇|Docker和 K8s 到底啥关系?想学K8s,必须得先学 Docker 吗?

实现了同一主机上容器进程间的相互隔离。容器的原理NameSpaces:隔离进程,让进程只能访问到本命名空间里的挂载目录、PID、NetWork
2022年5月16日
其他

如何在 Go 函数中获取调用者的函数名、文件名、行号...

回溯调用栈获取调用者的信息的方法,虽然强大,不过频繁获取这个信息也是会对程序性能有影响。我们的业务代码不应该依赖于它来实现,它发挥作用的地方更多的是对业务透明的一些类库在记录信息的时候才会被用到。-
2022年5月5日
其他

图解算法基础--快速排序,附 Go 代码实现

的算法,大概率要被挂,今天写个快排的基础文章,后面看情况再把归并和堆排序写一写,至于选择排序、冒泡排序这种时间复杂度高的就不写了,有兴趣的可以找书自己看一下。文中算法的实现是用
2022年3月7日
其他

写了 30 多个 Go 常用文件操作的示例,收藏这一篇就够了

data)}使用缓存读有缓存写也有缓存读。缓存reader会把一些内容缓存在内存中。它会提供比os.File和io.Reader更多的函数,缺省的缓存大小是4096,最小缓存是16。package
2022年2月28日
其他

盘点一下结构体标签在Go中的应用

类型的值,它描述了字段的标签。上面我们谈到了结构体标签的使用规范,如果遵循规范给字段设置了标签后,就可以使用StructTag的Get方法解析标签的值并返回你指定的键的“值”。func
2021年11月2日
其他

用手写一个工具的过程讲清楚Go反射的使用方法和应用场景

今天来聊一个平时用的不多,但是很多框架或者基础库会用到的语言特性--反射,反射并不是Go语言独有的能力,其他编程语言都有。这篇文章的目标是简单地给大家梳理一下反射的应用场景和使用方法。我们平时写代码能接触到与反射联系比较紧密的一个东西是结构体字段的标签,这个我准备放在后面的文章再梳理。我准备通过用反射搞一个通用的SQL构造器的例子,带大家掌握反射这个知识点。这个是看了国外一个博主写的例子,觉得思路很好,我又对其进行了改进,让构造器的实现更丰富了些。本文的思路参考自:https://golangbot.com/reflection/
2021年10月26日
其他

关于Go程序错误处理的一些建议

Go的错误处理这块是日常被大家吐槽较多的地方,我在工作中也观察到一些现象,比较严重的是在各层级的逻辑代码中对错误的处理有些重复。比如,有人写代码就会在每一层都判断错误并记录日志,从代码层面看,貌似很严谨,但是如果看日志会发现一堆重复的信息,等到排查问题时反而会造成干扰。今天给大家总结三点Go代码错误处理相关的最佳实践给大家。这些最佳实践也是网上一些前辈分享的,我自己实践后在这里用自己的语言描述出来,希望能对大家有所帮助。认识errorGo程序通过error类型的值表示错误error类型是一个内建接口类型,该接口只规定了一个返回字符串值的Error方法。type
2021年9月27日
其他

你知道K8S暴露服务的方式有哪些吗?

Kubernetes支持多种将外部流量引入集群的方法。ClusterIP、NodePort和Ingress是三种广泛使用的资源,它们都在路由流量中发挥作用。每一个都允许您使用一组独特的功能和折衷方案来公开服务。背景默认情况下,Kubernetes上运行的服务都是在自己的
2021年8月31日
其他

怎么把一个Java应用打包成Docker镜像

怎么把Java应用打包成Docker镜像?对熟悉Docker的同学这应该是一个很简单的问题,把项目打包成JAR包然后在Dockerfile里用ADD命令把JAR文件放到镜像里,启动命令设置执行这个JAR文件即可。比如一个使用Maven构建的Spring应用就可以用下面这个Dockerfile构建镜像。FROM
2021年8月10日
其他

试了试Docker桌面应用自带的K8s集群,一个字“简单”

前言之前给大家介绍过几种在笔记本电脑上安装Kubernetes集群的工具,虽然安装起来不太繁琐但是多多少少还是需要花一些时间的,对于不想瞎倒腾,就想快速安装个本地集群开始学习和测试的同学,推荐你们试一试Docker桌面应用里自带的Kubernetes集群。其实我也是之前用Minikube安装的集群莫名其妙坏掉启动不起来后,偶然发现Docker桌面应用里内嵌了一个Kubernetes集群,试了试效果感觉还是挺不错的。下面我带大家简单过一下启用集群方法,全程几乎就是点点点,也不需要做啥。启用Kubernetes也不知道是什么时候开始(反正老早就有了,我这个是前年装的...一直没升级过),Docker的桌面应用除了提供Docker
2021年7月12日
自由知乎 自由微博
其他

Go语言的IO库那么多,我该怎么选?

带缓冲的流读取和写入(比如按行读写)。除了这几种实现外常用的还有ioutil工具库包含了很多IO工具函数,编码相关的内置库encoding/base64、encoding/binary等也是通过
2021年6月23日
其他

利用Kubernetes搭建便携式开发环境之MySQL和Redis

:https://medium.com/oracledevs/getting-started-with-the-mysql-operator-for-kubernetes-8df48591f592
2021年6月9日
其他

在容器里设置GOMAXPROCS的正确姿势

高于真正可使用的核心数后会导致Go调度器不停地进行OS线程切换,从而给调度器增加很多不必要的工作。目前
2021年5月30日
其他

用Kubernetes搭建Etcd集群和WebUI

这个单节点Kubernetes集群。我以前的文章里有详细介绍过安装步骤,我把他放在这里供大家参考。Minikube-运行在笔记本上的Kubernetes集群Kubernetes
2021年5月16日
其他

Goroutine Local Storage的一些实现方案和必要性讨论

Java的ThreadLocal是Java为每个线程提供的专用存储,把一些信息放在ThreadLocal上,可以用于来简化上层应用的API使用。一个显著的应用场景是,有了ThreadLocal后,就不需要在调用栈里的每个函数上都增加额外的参数来传递一些与调用链和日志链路追踪相关的上下文信息了。Go
2021年5月2日
其他

gRPC的平滑关闭和在Kubernetes上的服务摘流方案总结

平滑关闭和服务摘流是保证部署了多节点的应用能够持续稳定对外提供服务的两个重要手段,平滑关闭保证了应用节点在关闭之前处理完已接收到的请求,以前在文章「学习用Go编写HTTP服务」里给大家介绍过怎么用net/http库提供的
2021年4月4日
其他

借助 Pod 删除事件的传播实现 Pod 摘流

数量的上线。在本系列的下一也是最后一部分,我们将介绍如何使用它来控制同时发生的节点驱逐事件的数量。推荐阅读如何优雅地关闭Kubernetes集群中的PodDeployment应用详解
2021年3月16日
其他

如何优雅地关闭Kubernetes集群中的Pod

(SIGTERM)。节点上的kubelet将最多等待指定的宽限期(在pod上指定,或从命令行传入;默认为30秒)然后关闭容器,然后强行终止进程(使用SIGKILL)。注意,这个宽限期包括执行
2021年3月10日
其他

Kubernetes群集的零停机服务器更新

的方法,以确保在对节点进行更改时,没有任何工作负载在运行。或者,如示例中所述,如果要完全替换群集(例如替换VM镜像),我们希望将工作负载从旧节点移到新节点。在这两种情况下,我们都希望避免调度新的
2021年3月4日
其他

来了解一下K8S的Operator模式

API中的一个端点,用于存储一堆特定类型的API对象。它允许我们通过向集群添加更多种类的对象来扩展Kubernetes。添加新种类的对象之后,我们可以像其他任何内置对象一样,使用
2021年1月28日
其他

内存对齐 | 原来字段顺序还能影响结构体占用的内存空间

字节对齐,那么操作系统就可以高效地一次定位到数据,无需多次读取、处理对齐运算等额外操作。内存对齐的原则是:将数据尽量的存储在一个字长内,避免跨字长的存储。Go
2021年1月24日
其他

Go指针的使用限制和突破之路

"42"}上面的写法尽管很繁琐,但在这里并不是一件坏事,因为这些功能应该很谨慎地使用。不要试图引入一个uintptr类型的临时变量,因为它可能会破坏代码的安全性如果改为下面这种用法是有风险的:tmp
2021年1月10日
其他

Kubernetes--玩转Pod滚动更新123

前言今天推荐一篇关于Kubernetes上服务滚动更新相关的配置选项的文章,文章列出了最常用的几个配置项,解释了他们是怎么影响调度器对服务进行滚动更新的,同时还带出了Kubernetes项目中Pod这个逻辑单元的Ready状态是怎么确定的,并不是容器运行起来后Pod就进入Ready状态的。总之个人觉得是篇非常好的普及Kubernetes基础的文章,文章由本人完全手工翻译,尽量做到通顺易懂,英文好的同学可以直接看原文。原文标题:Kubernetes
2021年1月6日
其他

觉得WaitGroup不好用?试试ErrorGroup吧!

99了解ErrorGroup的使用方法后,我们再来看看这个并发同步原语的实现原理。ErrorGroup的实现原理ErrorGroup原语的结构体类型errorgroup.Group定义如下:type
2020年12月23日
其他

常用限流算法的应用场景和实现原理

在高并发业务场景下,保护系统时,常用的"三板斧"有:"熔断、降级和限流"。今天和大家谈谈常用的限流算法的几种实现方式,这里所说的限流并非是网关层面的限流,而是业务代码中的逻辑限流。限流算法常用的几种实现方式有如下四种:计数器滑动窗口漏桶令牌桶下面会展开说每种算法的实现原理和他们自身的缺陷,方便以后我们在实际应用中能够根据不同的情况选择正确的限流算法。计数器算法思想计数器是一种比较简单粗暴的限流算法,其思想是在固定时间窗口内对请求进行计数,与阀值进行比较判断是否需要限流,一旦到了时间临界点,将计数器清零。固定时间窗口面临的问题计数器算法存在“时间临界点”缺陷。比如每一分钟限制100个请求,可以在00:00:00-00:00:58秒里面都没有请求,在00:00:59瞬间发送100个请求,这个对于计数器算法来是允许的,然后在00:01:00再次发送100个请求,意味着在短短1s内发送了200个请求,如果量更大呢,系统可能会承受不住瞬间流量,导致系统崩溃。(如下图所示)固定时间窗口所以计数器算法实现限流的问题是没有办法应对突发流量,不过它的算法实现起来确实最简单的,下面给出一个用Go代码实现的计数器。代码实现type
2020年12月20日
其他

并发编程-信号量的使用方法和其实现原理

什么是信号量信号量是并发编程中常见的一种同步机制,在需要控制访问资源的线程数量时就会用到信号量,关于什么是信号量这个问题,我引用一下维基百科对信号量的解释,大家就明白了。信号量的概念是计算机科学家
2020年12月15日
其他

项目改用GoModules管理依赖的方法和经验总结

Modules终极入门(文章链接:https://juejin.cn/post/6844903433846145038)。今天的文章我想跟大家聊一下我们项目在从govendor迁移到Go
2020年12月9日
其他

深入理解StatefulSet,用Kubernetes编排有状态应用

前言作为一个后端工程师,因为负责的大部分项目都是Web服务这类的“无状态应用”,在平时工作中接触到的最常用的Kubernetes控制器是Deployment,但是Deployment只适合于编排“无状态应用”,它会假设一个应用的所有
2020年12月7日
其他

三种传递gRPC动态参数方式的使用体验

gRPC是一个远程调用框架,使用Protobuf做为信息的载体来完成客户端和服务端的数据传输。关于怎么定义Protobuf消息、搭建gRPC服务在之前的系列文章中都有提及,今天来说一下在使用gRPC和Protobuf的过程中怎么传递动态参数。首先说明一下,这里所说的动态参数指的是在定义Protobuf消息时还不能确定其具体内容的复合类型字段,简单的说就是消息里的这个字段我们想传一个类似JSON对象、Map字典、结构体等等这样的组合值,但是JSON里有哪些字段、每个字段值是什么类型或者Map字典键值的类型我们在定义消息时还无法确定(能确定就可以定义子消息嵌套进来了,不在本文的讨论范围内),把这样的Protobuf消息字段叫做动态参数。针对通过Protobuf传递动态参数的需求,官方文档里并没有给出标准的解决方案,目前我所知道的能够通过bytes、Map以及proto.Struct这三种Protobuf消息字段的类型实现,每种方式也都有自己的优势和劣处,如果你碰巧知道更好的实现方案,欢迎在评论里留言讨论。下面我们就来看一下使用这三种消息字段的类型如何实现动态参数的传递。使用bytes传递JSON对象参数Protobuf里的bytes类型的字段编码成Go代码后对应的是Go里的字节切片[]byte类型。所以我们可以把动态参数的字段类型定义成bytes类型,这样客户端把JSON对象传递到服务端后,服务端能直接对动态参数里包含的JSON对象做解码操作,省去了一次从string到[]byte的类型转换。举个例子来说,在下面的Protobuf消息定义里info字段的类型是bytesrpc
2020年11月12日
其他

ConfigMap用管理对象的方式管理配置

在今天的文章中我将介绍Kubernetes中的ConfigMap对象。它的主要用途什么,为什么要用ConfigMap以及在Kubernetes里通常是如何使用ConfigMap的管理应用配置的。在学习本文的内容前需要对Kubernetes,pod这些概念有基本的了解。想实践练习这些内容需要在电脑上先安装kubectl和minikube。所有这些准备工作都可以在写给开发工程师的Kubernetes学习笔记系列前面的文章里找到操作指南。什么是ConfigMap能够灵活管理应用的配置是一个系统能否长期成功运转的一个关键因素,尤其是在应用分布式微服务时更是如此。再将应用部署到测试,开发和生产等多个环境时,由于环境不同,将配置放到应用程序的镜像里不是一个好的做法。理想情况下,你会希望将配置与应用程序镜像分开管理好匹配不同的部署环境。在Kubernetes项目里这就是ConfigMap
2020年10月31日
其他

gRPC服务注册发现及负载均衡的实现方案与源码解析

今天聊一下gRPC的服务发现和负载均衡原理相关的话题,不同于Nginx、Lvs或者F5这些服务端的负载均衡策略,gRPC采用的是客户端实现的负载均衡。什么意思呢,对于使用服务端负载均衡的系统,客户端会首先访问负载均衡的域名/IP,再由负载均衡按照策略分发请求到后端具体某个服务节点上。而对于客户端的负载均衡则是,客户端从可用的后端服务节点列表中根据自己的负载均衡策略选择一个节点直连后端服务器。Etcd软件包的naming组件里提供了一个命名解析器(naming
2020年10月25日
其他

图文结合,白话Go的垃圾回收原理

运行时程序长时间挂起的问题。三色标记清除法从v1.5版本Go实现了基于三色标记清除的并发垃圾收集器,注意三色标记这个算法不是Go的垃圾收集器独有的。这个算法背后的核心思想是由Edsger
2020年10月11日
其他

[译]Go语言常用文件操作汇总

Go官方提供的文件操作标准库分散在os、ioutil等多个包中,里面有非常多的方法涵盖了文件操作的所有场景,不过因为我平时开发过程中需要直接操作文件的场景其实并不多,在加上Go标准库的文档太难搜索,每次遇到要使用文件函数时都是直接Google查对应的函数。偶然查到国外一个人在2015年写的博客,他用常用的文件函数汇总了30个文件操作场景,包括四大类:基本操作、读写操作、文件压缩、其他操作。每一个文件操作都给了代码示例。写的非常好,强烈推荐你阅读一下,浏览一下它的目录,然后放到收藏夹里吃灰,万一哪天用到了还能拿来参考一下。原文链接:https://www.devdungeon.com/content/working-files-go作者:NanoDano作者主页:https://www.devdungeon.com/users/nanodano介绍一切皆文件UNIX
2020年9月30日
其他

学练结合,快速掌握Kubernetes Service

今天这篇文章里我们来讲一下Kubernetes里的Service对象。其实前面的文章《Kubernetes初体验--部署运行Go项目》里我们已经与Service有过一次短暂接触了,在那篇文章里我说用Deployment对象部署完应用后还需要向外界暴露入口才能通过HTTP访问到Kubernetes集群里的应用Pod,当时使用的是这样一条命令,其实就是创建的Service对象:kubectl
2020年9月24日
其他

我在暴躁同事小张的胁迫下学会了Go的交叉编译和条件编译

(小张明显比我有钱,我的Mac是公司发的,人家的外星人是为打游戏自己买的)。那么假如我编写的代码依赖了系统底层平台或处理器架构特性的Go包时,比如说我上周在文章《Go服务迁到K8s后老抽风重启?
2020年9月19日
其他

Go服务迁到K8s后老抽风重启? 记一次完整的线上问题解决过程

来强制转换,但运行程序后,发现不起作用,/tmp/go-app1-stderr.log没有任何信息流入,panic信息照样输出到标准错误里。最终方案关于原因,搜索了一下,幸运的是
2020年9月13日
其他

解密Go协程的栈内存管理

应用程序的内存会分成堆区(Heap)和栈区(Stack)两个部分,程序在运行期间可以主动从堆区申请内存空间,这些内存由内存分配器分配并由垃圾收集器负责回收。栈区的内存由编译器自动进行分配和释放,栈区中存储着函数的参数以及局部变量,它们会随着函数的创建而创建,函数的返回而销毁。网管碎碎念:堆和栈都是编程语言里的虚拟概念,并不是说在物理内存上有堆和栈之分,两者的主要区别是栈是每个线程或者协程独立拥有的,从栈上分配内存时不需要加锁。而整个程序在运行时只有一个堆,从堆中分配内存时需要加锁防止多个线程造成冲突,同时回收堆上的内存块时还需要运行可达性分析、引用计数等算法来决定内存块是否能被回收,所以从分配和回收内存的方面来看栈内存效率更高。在Go应用程序运行时,每个goroutine都维护着一个自己的栈区,这个栈区只能自己使用不能被其他goroutine使用。栈区的初始大小是2KB(比x86_64架构下线程的默认栈2M要小很多),在goroutine运行的时候栈区会按照需要增长和收缩,占用的内存最大限制的默认值在64位系统上是1GB。栈大小的初始值和上限这部分的设置都可以在Go的源码runtime/stack.go里找到://
2020年9月12日
其他

图解Go内存管理器的内存分配策略

关于Go的内存分配在Go语言里,从内存的分配到不再使用后内存的回收等等这些内存管理工作都是由Go在底层完成的。虽然开发者在写代码时不必过度关心内存从分配到回收这个过程,但是Go的内存分配策略里有不少有意思的设计,通过了解他们有助于我们自身的提高,也让我们能写出更高效的Go程序。Go内存管理的设计旨在在并发环境中快速运行,并与垃圾回收器集成在一起。让我们看一个简单的示例:package
2020年9月5日
其他

K8s上的Go服务怎么扩容、发版更新、回滚、平滑重启?教你用Deployment全搞定!

19m默认情况下,Deployment会将pod-template-hash添加到它创建的ReplicaSet的名称中。比如这里的my-go-app-864496b67b最后
2020年9月2日
其他

MySQL读锁的区别和应用场景分析

读锁的概念和区别如果在MySQL的事务里查询数据,然后在同一事务中插入或更新相关数据,常规的SELECT语句不能提供足够的保护。其他并行的事务可以更新或删除第一个事务里刚查询的相同行。InnoDB支持两种类型的读锁,提供了额外的安全性:SELECT
2020年8月29日
其他

Go内存管理之代码的逃逸分析

基本上,每种编程语言都有其自己的内存模型。每个变量,常量都存储在内存的某个物理位置上,这些存储位置通过内存指针访问。至于变量,就是程序里赋予内存存储位置的名称。程序可以根据需要进行操作,并且可以将新值分配给相同的内存存储位置。而常量也是赋予内存存储位置的名称,但是程序不能将新值分配给相同的存储位置(意思就是常量是恒定值,不能被重新赋值)。我们都知道,程序运行时使用的内存被分为两个区:堆和栈。那么如何得知变量是分配在栈(stack)上还是堆(heap)上呢?对于手动管理内存的语言,比如C/C++,使用malloc或者new申请的变量会被分配到堆上。但是Go并不是这样,虽然
2020年8月26日
其他

Kubernetes控制器--副本集ReplicaSet

Kubernetes最核心的功能就是编排,而编排操作都是依靠控制器对象来完成的,高级的控制器对象控制基础的控制器对象,基础的控制器对象再去控制Pod,Pod里面再包容器。Kubernetes项目里API对象的层级结构大概就是这样。前面的文章:(Kubernetes
2020年8月20日
其他

如何避免用动态语言的思维写Go代码

由于招聘市场上Go工程师的供给量不足,所以在招人的时候我们招了不少愿意转型用Go语言进行开发的PHP工程师,不过虽说换了个语言,在他们代码的时候还是能发现很多PHP的影子。if语句后面非要带括号这种问题就不说了,这属于不懂事,gofmt就会强行把你掰过来。最大的问题还是因为以前用惯了PHP的数组,到写Go代码时还是不习惯先定义类型后使用这种习惯。还有就是以前写PHP的时候可能没养成使用异常的习惯,在返回值里约定特殊值来代表错误。所以后面我在团队内部做过一次培训,专门分享了怎么建立正确的Go编码习惯,以下是节选了当时演讲稿的一部分。其实不是专门针对PHP程序员,可能写动态语言的程序员在开始用Go写代码时都容易犯的一些错误。Go编程的注意事项及建议接下来我们会说几个PHP程序员在刚开始用Go写程序时几个需要改变的编码习惯和要注意的地方。尽量使用结构体切片代替字典我们有的新同学特别爱使用Go里面的Map,有的时候还是切片里边套Map,比如我看一开始有的同学把一些配置信息放在map[string]string类型的Map里,多个的话再把Map放进切片里,比如这样。var
2020年8月16日
其他

浅析Kubernetes Pod重启策略和健康检查

使用Kubernetes的主要好处之一是它具有管理和维护集群中容器的能力,几乎可以提供服务零停机时间的保障。在创建一个Pod资源后,Kubernetes会为它选择worker节点,然后将其调度到节点上运行Pod里的容器。Kubernetes强大的功能可使应用程序的容器保持连续运行,还可以根据需求的增长自动扩展系统。除此之外在Pod或容器出现故障时Kubernetes还可以让系统实现"自愈"。在本文中,我们将介绍如何使用Kubernetes内置的livenessProbe和readinessProbe来管理和控制应用程序的运行状况。Pod的重启策略Kubernetes自身的系统修复能力有一部分是需要依托Pod的重启策略的,
2020年8月12日
其他

Kubernetes Pod入门指南

Pod是Kubernetes项目里定义的最小可调度单元,是Kubernetes对应用程序的抽象。在这篇文章里我将会介绍Kubernetes里Pod的基本概念,使用方式,生命周期以及如何使用Pod部署应用。读这篇文章的朋友我会默认你已经了解Kubernete是用来解决什么问题的,以及电脑上已经安装了Minikube这个能试验Kubernetes功能的工具。如果尚未做好这些准备工作,推荐先去看下面的两篇文章做好准备工作后再来学习这里的内容。你一定要了解的Kubernetes运行在笔记本上的Kubernetes集群什么是Pod在Kubernetes的API对象模型中,Pod是最小的API对象,换一个专业点的的说法可以这样描述:Pod,是
2020年8月5日
其他

Docker容器的"单进程模型"

刚开始学Docker的时候因为不知道Docker跟以前在VirtualBox里安的虚拟机还有Vargrant有啥区别,我都是习惯性的把开发环境里用的东西往单个容器里塞。后来看网上的教程还有别人分享的案例多了后,才知道把应用容器化的第一步是:要把应用用到的东西拆解放到多个容器里。慢慢地我发现不少人刚开始学Docker时候跟我一样都有刚接触时把Docker当虚拟机来用的问题,比如我特别早以前发过一篇文章《用Docker-Compose搭建Laravel开发环境》里,我用三个分别装着PHP、MySQL和Nginx的容器搭建了一个开发环境。有读者就问了这么一个问题:Laravel不过那会儿我对Docker的掌握程度也仅限在搭建个开发环境这个级别,很多原理也不太理解所以只是告诉他每个容器里只能有单一的进程,这样更好管理、扩展之类的,希望这个大哥最后找到了正确的学习方法。不过在许多关于Docker的博客文章和教程里列举的最佳实践里确实都有:"每个容器只运行一个进程"这样的说法。为什么存在此规则?为什么不在单个容器中运行Nginx,PHP,Go或者更多进程?通过最近的文章《容器和虚拟机到底有啥区别?》我们聊了,容器不像虚拟机那样拥有独立的操作系统,容器只是通过Linux的Namespaces、Cgroups实现了进程级别的隔离。虽然在容器里看不见宿主机上的其他进程,但归根结底它还只是一个运行在宿主机上的进程,所以就不具备操作系统的进程管理能力。每个容器里只运行一个进程这个说法其实不太准确,因为像Nginx在启动后主进程会再开启若干个Worker进程负责请求的处理,Apache更是会为每个请求创建一个进程。容器的"单进程模型",并不是指容器里只能运行"一个"进程,而是指容器没有管理多个进程的能力。这是因为容器里的主进程(PID=1
2020年7月30日
其他

YAML,另一种标记语言?不止是标记语言!

plop数字类型YAML可以识别数字类型。我们在上面看到了浮点和整数。YAML还支持其他几种数字类型。整数可以用十进制、十六进制或八进制表示,Ox表示一个值是十六进制的,前导零表示一个八进制值。
2020年7月24日