使用 Docker Compose 实现滚动更新部署
最近在写一个Golang的微服务项目,受限于测试和生产环境交付的时候都无法使用到Kubernetes,所以准备使用Docker Compose部署,记录一下实现方式。
思路
变更容器编排文件docker-compose.yaml
获取当前启动的容器id,标识为旧容器
更新并调度服务比当前容器数量多的指定数量
杀掉标识的旧容器
清理杀掉的旧容器
重新调度服务容器数量为期望数量
shell 脚本实现
备注:此脚本需在 docker-compose.yaml 编排文件所在目录执行。或者自己改脚本,cd 进目标目录执行
12345678910111213141516171819202122# 1. 更新 docker-compose.yaml,有很多选择,你可以手动更新,也可以使用 ci 自动使用新的编排文件覆盖。总之就是把当前目录下的编排文件变成你期望的最新的,有可能是只改了镜像,或者其他# 取到使用当前目录下的编排文件启动的服务容器idprevious_container=`docker-compose ps -q`# 将容器数量调度到指定值,此值需要大于当前服务的容器数量docker ...
使用 log-pilot + elk 搭建 docker stdout 日志解决方案
最近在写一个Golang的微服务项目,受限于企业内部网络等各种问题,日志无法上云只好自建日志收集管理平台了,记录一下实现方式。
整个环境从服务到elk到log-pilot均使用docker-compose部署
log-pilot 介绍log-Pilot 是一个阿里云开源的一款智能容器日志采集工具,它不仅能够高效便捷地将容器日志采集输出到多种存储日志后端,同时还能够动态地发现和采集容器内部的日志文件。log-pilot 通过声明式配置实现强大的容器事件管理,可同时获取容器标准输出和内部文件日志,解决了动态伸缩问题,此外,log-pilot 具有自动发现机制,CheckPoint 及句柄保持的机制,自动日志数据打标,有效应对动态配置、日志重复和丢失以及日志源标记等问题。
log-Pilot代码仓库
log-pilot 特性
一个单独的 log 进程收集机器上所有容器的日志。不需要为每个容器启动一个 log 进程。
支持文件日志和 stdout
docker log dirver 亦或 logspout 只能处理 stdout,log-pilot 不仅支持收集 stdout 日志,还可以 ...
搭建基于 Kubernetes 生产可用的日志和监控系统
前言本篇文章涉及很多 Kubernetes 基础知识,包括但不限于以下资源对象:
Namespace
Pod
Deployment
Service
Headless Service
Volume
PersistenVolume
PersistenVolumeClaim
StatefulSet
DaemonSet
Ingress
Role
ClusterRole
如果这些东西你还很陌生,请转战Kubernetes中文官方文档
基础设施安装工具1yum install bind-utils -y
内网免密登录1ssh-keygen
master 节点的 pub key 加入各节点的 auth key
初始化集群为了节省时间使用了 sealos 工具来搭建 K8S 集群,如果你想了解使用 Kubeadm 部署 K8S 集群可以参考笔者的另一篇文章Kubeadm 安装 Kubernetes V1.22.2 踩坑手记
工具12wget -c https://sealyun-home.oss-cn-beijing.aliyuncs.com/sealos/latest/se ...
浅析 Golang 内存机制(内存分配、GC、内存逃逸)
内存分配
Go 程序在启动时,会向操作系统申请一定区域的内存,分为堆(Heap)和栈(Stack)。
堆(Heap)
一般来讲是人为手动进行管理,手动申请、分配和释放。所涉及的内存大小并不定,一版会存放比较大的对象。分配相对较慢涉及到的指令动作相对较多。
在 Go 语言中,堆内存由程序申请分配,由 GC(Garbage Collection)负责回收
栈(Stack)
由编译器进行管理,自动申请、分配、释放。一般不会太大,我们常见的函数参数、局部变量等等都会放在栈上。
在 Go 语言中,栈内存会随着函数的调用而进行分配,随着函数的调用结束而回收
性能上,栈内存的使用和回收会更快一些,尽管 Golang 的 GC 很高效,但过程中还会在标记准备阶段和标记结束阶段进行 STW,因此,会优先使用栈内存进行分配(因为栈内存更高效,不需要 GC,所以会尽可能将内存分配到栈上),在某些特殊场景下可能会发生内存逃逸到堆上
GC(Garbage Collection)标记清除法在 Go 1.3 之前的版本使用的是标记清除法(mark and sweep),大致流程如下:
暂停程序业 ...
浅读 Go 优秀开源项目源码—Gin框架
Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。
Gin 是目前 Go 里面使用最广泛的框架之一了,弄清楚 Gin 框架的原理,有助于我们更好的使用 Gin。通过浅读 Gin 框架源码,大致总结一下它的一些核心实现。
从一个 Demo 入手下面这段代码便是使用 Gin 编写一个简单的只有一个接口的 Go server 端程序,详细使用方式参考官方文档:Gin Web Frameword
123456789101112131415161718192021222324252627package mainimport ( "fmt" "log" "time" "github.com/gin-gonic/gin")func main() { r := gin.Default() // 注册路由 r.GET(" ...
基于 Consul 实现 gRPC 服务注册与发现
什么是服务注册与发现,为什么需要服务注册发现
服务注册
服务进程在注册中心注册自己的元数据,一般包括 Host 和 Port,有时候还有身份验证信息,协议,版本号以及运行环境等信息。
服务发现
客户端进程向服务注册中心发起查询,来获取依赖的服务的信息,然后向其发送请求。服务发现一个重要的作用是提供给客户端进程一个可用的服务列表。
简单的说,当服务A需要依赖服务B时,服务发现中间件需要告诉服务A哪些地址是服务B的可用地址,这就是服务注册发现需要解决的问题。
服务注册
客户端注册
服务自身负责注册与注销工作,当服务启动后注册线程向注册中心注册,当服务停止时注销自己。
代理注册
当服务启动后以某种方式通知代理服务,代理服务向注册中心发起注册工作。
健康检测
被动检测
服务主动向注册中心发送心跳消息,时间间隔可以自定义。注册中心如果在指定周期内未收到服务节点的心跳消息,则将其从该服务可用节点列表中移除
主动检测
服务注册中心指定时间间隔内向所有列表中的服务节点发送心跳检测,如果指定周期内未成功则主动移除该节点。
服务发现
客户端发现
客户端向注册中心发起请求查询 ...
使用 Opentracing 实现 Golang 链路追踪
为什么需要链路追踪在微服务架构系统中,请求在各服务之间流转,调用链路错综复杂,一旦出现了问题和异常,定位问题相当困难。链路追踪系统可以追踪并记录请求在系统中的调用顺序、调用时长等一系列关键信息,从而帮我们更简单的定位服务异常。
OpentracingOpentracing 是分布式链路追踪的一种规范标准,是 CNCF(云原生计算基金)孵化的项目之一。和一般规范标准不同,Opentracing 不是传输协议、也不是消息格式上的规范标准,而是一种语言层面上的 API 标准。只要在某链路追踪系统实现了 Opentracing 规定的接口,符合 Opentracing 定义的表现行为,那么就可以说该应用符合 Opentracing 标准。这意味着,开发者只需要修改少量的配置代码,就可以在符合 Opentracing 标准的链路追踪系统之间自由切换。
数据模型SpanSpan 是一条链路追踪的基本组成要素,一个 Span 表示一个独立的工作单元,比如一次函数调用,一次 RPC 请求,Span 会记录一些基本要素:
操作/行为名称
开始时间
结束时间
Tags(一组零个或多个 key: ...
「在一个内卷的时代,我们该如何谈论幸福」课堂笔记
整堂课的“题”,老师整体上是基于罗曼罗兰的这句话展开的:
世界上只有一种真正的英雄主义,就是当你认清了生活的真相后,你仍然还热爱它。
为什么会内卷
内卷是一种在资源有限,且没有增量资源的情况下,整个社会对存量资源争夺加剧的一种社会现象。
资源有限,对资源的需求无限。
所以内卷出来之后出来一个词,就是躺平。我卷不动了肯定就躺了,我不想跟你争夺了,我就要躺平啊。
高校里的编制为什么那么困难,编制就是那么点有限的,争夺这些编制的人多着呢,他不提高要求的话怎么筛选啊。
只不过是因为时间的变化、社会的发展,对我们每个人的要求越来越高了。
鸡娃现象
是我们的内心不够坚定,被这种教育的洪流给带跑了。
幸福为什么那么难生物学家在解析幸福的时候是把这个问题指向动物和人类的身体机制的。生物学家举了一个例子:
大马哈鱼,溯江而上,产卵而死。我们身上的这种身体机制为了繁衍连母体的生命都可以牺牲,幸福怎么可以被称为重要的追求呢。
自然选择出的生理机制只是服务于人类生存的繁衍,根本就没有增加这种幸福快乐的考虑。然而,我们产生了一种错觉,就是我们小的时候很幸福呀。人类在幼儿阶段是最明显的一个动物性的阶段。 ...
Kubernetes 集群部署最新版 Ingress-Nginx
简介
ingress-nginx 是 Kubernetes 的入口控制器,使用 Nginx 作为反向代理和负责均衡器。
如引用所写的那样,ingress-nginx 其实就是使用 Nginx 作为 Kubernetes 集群入口的反向代理和均衡器。对于 Nginx 我们应该都很熟悉,或者说至少不陌生。那么什么是ingress呢。
什么是 Ingress
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。Ingress 公开了从集群外部到集群内部服务的 HTTP 和 HTTPS 路由。流量路由由 Ingress 资源定义的规则控制。
下图是一个将所有流量发送到同一个 Service 的简单 Ingress 示例:
Ingress 资源和所有其他 Kubernetes 资源一样,Ingress 需要使用apiVersion、kind、metadata字段,Ingress 通常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,不同的 Ingress 控制器支持不同的注解。
Ingress 规约 提供了配置负 ...
使用 Helm 在 Kubernetes 集群安装最新版 Traefik
简单介绍
Traefik 是一个开源的边缘路由器,他负责接收系统的请求,然后使用合适的组件对这些请求进行处理。
下图为 traefik 的架构图,traefik 的官方文档地址是:https://doc.traefik.io/traefik/
核心概念providersTraefik 中的配置发现是通过 Providers 实现的,Provider 可以是编排工具、容器引擎、或者 KV 存储等。
支持的 Providers 文档:https://doc.traefik.io/traefik/providers/overview/#supported-providers
entrypointsentrypoints 是 Traefik 的网络入口点,他们定义了将接收数据包的端口,以及侦听 TCP 还是 UDP。
配置文档参考:https://doc.traefik.io/traefik/routing/entrypoints/
routers路由器负责将传入请求连接到可以处理他们的服务,在这个过程中可能会使用中间件来更新请求,或者在将请求转发给服务之前做一些处理。
配置文档参考 ...