Golang逃逸分析
逃逸分析,看着一个非常高大上的名词,很多人第一次听到它的感觉会觉得它好厉害的样子,其实说到底它很好理解,并不复杂。之前一直没有写也是有原因的,因为其实在实际中,我真的很难用上它。这次写也是有原因的,因为有人催更了…其实拖了有一段时间了,最近终于忙完了,开始补债了。 栈和堆在说逃逸分析之前,我们需要有一些前置知识点 栈我们常说的栈是一种数据结构,当然这里说的栈特指我们在谈论内存分配的时候说的栈。它的作用是在函数调用的过程中保存函数的参数局部变量等数据。而且当函数调用完毕后,它所使用的栈空间将立即释放。所以它“便宜”。 堆堆的概念我们就应该非常熟悉了,它用来存放很多需要使用的对象,这些对象的生命,在 go 里面是交给 GC 去管理的,当我们再也不使用的时候,GC 会将它们回收。所以它“贵”,因为它需要额外的做功才能将它回收掉。 为什么?那为什么需要堆?不用堆不行吗?其实答案显然不行,因为如果所有的变量对象都在栈上,用完了就扔掉,那么其他人想要再使用的时候就无法使用了。 那全部都在堆上不行吗?答案也很显然不行,因为栈便宜,用完就扔,堆很贵,你不能将所有的东西都扔给 GC,这样它要...
GopherChina2021 个人总结
今年本来没想着要去的,因为确实有点远,加上疫情之下不太方便,但是意料之外来了一张门票,那就必须去一下了,这次收获也不少,有了上次的经验,这次就听得很舒服,不像上次那样那么累了,这次能准确的知道什么应该仔细听,什么应该略过,所以这次的笔记就相对来说少一些,精炼一点。 这次去也面基了大佬,果然北京的都是大佬,都比我卷的厉害,以后还要多学习,哈哈哈,膜拜膜拜~ 基于 Golang 构建高可扩展的云原生 PaaS 平台端点 PaaS 介绍整个历程 主要是推 Erda,主要有以下几点个人觉得可以 自定义 pipeline 开箱即用 微服务治理 兼容 java 族(spring 那一套,还有 dubbo) 可观察性数据采集 个人总结:写个这的一定是 java 过来的,autowired 很 java 味道 https://github.com/erda-project/erda MOSN 云原生演进历程MOSN 之前就有听说的,我觉得很像给 Envoy 加个 buff CGO 并没有想的那么性能堪忧 通过 hacker 的方式可以在调用链路中加一层 filter 实现 想办法做到 ...
轻量级 k8s 应用日志收集方案 loki
微服务早已是一个过时的热词,同时,容器 和 k8s 的出现让它更一步成为了一种时尚。同样会带来很多附赠的问题,日志收集就是其中一个比较重要的问题。当应用容器化之后,需要查看日志,如果还需要登录服务器,找到对应目录,然后 tail 查看,成本太高了,极大的影响效率。当前其实日志收集方案很多,在实践了多个方案之后,我终于能在今天写出我个人认为我最喜欢的一个方案了 loki 我的需求技术上没有银弹,需要根据实际需求来选择方案,那么我的需求是这样的,你可以做个比较: 当前所有的应用是部署在 k8s 中的,需要收集所有的应用的日志到一个地方做展示 部署最好要轻量,对于性能要求并不高(当前日志量并不大) 日志展示方式友好,能支持基本的时间查询,或者是定位到某个关键字 可选方案从之前的公司包括个人的一些项目上都尝试过很多不同的组合和方案,列举出三个最具有可比性的方案:(以下为个人使用案例,并不能代表所有大众观点,图片来源本地测试服,线上日志不允许公开,但同样禁止转载~) ELK 这似乎是业界最成熟的日志收集方案之一了,因为无论你问哪个有点经验的程序员,提到日志收集,必然会给到这个,我当...
monitoror/monitoror 最轻量的监控大屏
一提到监控大屏,那第一想法就是 grafana 对吧,各种样式图形都非常好看,而且支持各种数据源。而今天要分享的是一个更加轻量的监控大屏 monitoror/monitoror 有了它能帮你快读构建一个的对于网站或者应用的监控页面,特别是在小应用数量多的时候非常简单易用,作为一个大屏展示时它我觉得它足够简洁 demo & repohttps://demo.monitoror.com/ https://github.com/monitoror/monitoror 优点 部署轻量 配置简单 大屏简洁 部署二进制部署https://monitoror.com/documentation/get-started/ 非常简单,只需要将二进制文件下载,然后按照要求配置对应的配置文件,就可以了 12chmod +x monitoror./monitoror 配置文件.env 1MO_CONFIG="./config.json" 配置文件config.json 12345678910111213141516171819202122...
k8s 意外集锦 - oom 的连锁反应
一开始觉得 oom 是一个常见问题,应该没有什么大问题,反正 k8s 集群会调度的,但其实它造成的连锁反应很恐怖。 问题描述具体简单描述过程:一台机器 OMM, 导致将对应的pod调度到了其他节点上,导致其他节点 OOM 然后开始疯狂输出日志信息,然后导致 master 磁盘不足开始清理并驱逐,然后导致驱逐(Evicted)的应用再次调度到其他节点,然后连锁反应,最终相关大量服务不可用…. pod 出现告警信息 The node had condition: [DiskPressure]. 总的来说就是一个 应用的 oom 不停的被调度来调度去,导致日志疯狂的输出,导致磁盘不足了。 问题解决设置合适的内存请求和限制条件限制单个应用的使用内存还是非常有必要的,免得出现很多意外的情况 1234567resources: requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi 应用 bug 修复代码 bug 肯定要修复的,这个毕竟是导致问题的主要原因 升级 ECS...
k8s 意外集锦 - configmap 挂载 目录 只读
OCI runtime create failed: /var/lib/docker/overlay2/6573e40fef5bc51b4e565ad9554f225806f05a9f9089cc9e210c0e35a80e6e1f/merged/etc/resolv.conf: read-only 报错信息123456789Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused"process_linux.go:424: container init caused \"rootfs_linux.go:58: mounting\\\"/var/lib/docker/containers/1ec387b2e168281ed480c5050b08893976ac84a2751691e1a9429ae6a...
k8s 小技巧
本博客持续更新…用于记录 k8s 使用过程中的很多的小技巧,也希望你能提供更多的小技巧来~ 图形化管理工具 lens图形化 k8s 管理工具: https://github.com/lensapp/lens 我觉得可以少部署一个 dashboard,并且比官方的 dashboard 好看很多 重启 deployment 命令我一开始总是 delete 一次 apply 一次,感觉很蠢,又换成调整 scle 但是还是很慢,查了之后发现原来本来就有重启的命令 1kubectl rollout restart deployment nginx-dep 查看链接配置信息1kubectl config view --minify --raw kubectx当你需要使用 kubectl 操作多个集群的时候,可以使用 kubectx 切换 context,非常方便 多集群管理切换工具:https://github.com/ahmetb/kubectx 更新 configmap 脚本对于配置文件 configmap 的更新我真的没有找到合适的命令,直接 使用 kubectl edit 那...
Weave Scope 监控 k8s 集群
之前一直在寻找一个 k8s 监控的工具,因为一直使用的是本地的 lens 的客户端,虽然使用上已经非常方便了,但是其实对于资源消耗的监控少了一点,有些资源消耗并不是能容易看到,并且服务间依赖是没有办法表现出来的,后来发现了 Weave Scope 满足了我的需求。 链接https://github.com/weaveworks/scope 特点 资源监控:能实时反映整个集群中的资源状况 cpu 内存 使用情况 并且支持各种角度 服务间依赖:能通过图形展现出服务之间访问的依赖关系 容器交互:实时查看日志和描述信息 支持插件:可以通过插件扩展 部署方便:一个命令即可部署完成 监控页面资源监控 可以清楚的看到每个 node 的资源使用情况 服务间依赖 因为内部服务与服务之间通过 rpc 进行交互,从这里可以很容易看出,某个服务被别的五个服务所依赖调用 容器交互 可以看到占用的 cpu 和内存的情况,然后占用的端口等,还有日志信息 部署支持直接部署在 k8s 集群中,不需要额外的任何配置 https://www.weave.works/docs/scope/latest/insta...
GopherChina2020 个人总结
之前去过几次相关 go 的线下 meetup,这次相对来说比较大型一些,两天的听下来还是比较烧脑的,光是记录的笔记都有近千行了,整体来说收获很大。 有的人问,值票价吗?我回答:对喜欢的投资没有不值得的。对我来说值了~ 有的人问,值得去吗?我回答:不一定,因为可能在很多大佬看来能听到的点不多(采访了几位现场的大厂观众,普遍表示只有其中 1 到 2 场满足他们的要求)但是如果你的小白或者一年到两年左右,还是能见识很多东西的。可能是我听多了,和之前自己学到的有点重复… 下面是个人精炼总结,全是个人总结,自己如果对这个知识或者相关点比较清晰的我就没有记录了。其中会伴随一些个人思考和疑问,可以小声 bb 。大会分 1和 2 会场,所以只能选其中一个听,我也是记录我自己听到的,另外一个会场不清楚(我交叉穿来穿去的)注意并不是有的老师讲的真的不好,而是对我个人来说意义不明显,可能由于知识点已经掌握,也可能是由于工作上确实用不到哦 最后会附上会上笔记,仅做个人使用,乱了也不管~ 最后无论如何,感谢每一位老师的付出~~~ 要点总结 分布式数据库设计难题:数据分片,节点加入和减少 如果让你设计一...
下一个 nginx?caddy 自动 https 真香
我们通常在部署 web 服务的时候往往会选择 nginx 作为最前面的一个狠角色,它的性能和能力大家也是有目共睹的,反向代理负载均衡等等。而作为后起之秀 caddy 却不被人所熟知,不过渐渐的也开始展露头角。今天我就来介绍这个 caddy ,为什么我会称它有可能成为下一个 nginx。 我先列举几个痛点你看下: nginx 的配置文件你是否感觉有时候有点臃肿 https 需要购买或者申请证书,然后配置是否觉得麻烦? linux 下安装 nginx 需要部分依赖 而 caddy 确实给我了一种眼前一亮的感觉。 使用官网:https://caddyserver.com/ 安装https://caddyserver.com/docs/download安装很简单,直接下载对应的二进制文件即可,或者按照对应到操作系统去安装也可以。没有其他依赖。 使用https://caddyserver.com/docs/getting-started一个命令就可以启动,caddy,默认会去当前目录下寻找 Caddyfile 配置文件,也可以通过 –config 去指定文件位置 123caddy ...
openfaas/faas 环境搭建和开发使用
serverless 大环境下出现了 faas,即 function as a service,函数即服务;其意思也非常好理解,就是能将一个函数作为一个服务进行使用,用户只需要编写一个函数功能即可,不需要额外去关心别的东西。https://github.com/openfaas/faas 是其中的一种实现方式。 环境准备以下环境在 mac 上进行搭建: 首先需要准备 docker 和 kubernetes 的环境,先做 k8s 的环境直接能通过 docker 桌面进行配置,已经算是很方便了。 安装步骤openfaas-cli1curl -sL https://cli.openfaas.com | sh namespace123git clone https://github.com/openfaas/faas-netescd faas-neteskubectl apply -f namespaces.yml password12345678$ cat passwd.sh # PASSWORD=$(head -c 12 /dev/urandom | sha1sum...
Golang Mutex 到底是否应该使用指针
在写 go 的时候,你使用 Mutex 的时候使用的是指针还是说没有使用指针,还是随意来? 前两天我收到了下面这样的一个 PR,我突然就想到了这个问题,于是就有了这篇博客。 我一开始的想法其实我一开始的想法很简单,因为我一直没有使用指针 在我的某些印象中我曾经记得,使用锁不申明为指针是一个代码规范类似的东西 大多数的(我看过的一些)源码中,没有见过将锁申明为指针的用法 但是当时我没有办法回答这个 PR,你总不能说我是一厢情愿吧…需要一个更加合理的解释 仔细分析上网搜索一番https://www.reddit.com/r/golang/comments/6uyf16/confusion_about_mutex_and_reference/ 很多类似的问题都在问(你不用点开,只是举个例子) 问题关键sync.Mutex 这个东西不能被 copy!(这个我之前也是知道的,毕竟都分析过源码了) 刨根问底虽然这个锁不能被拷贝,那么就应该被申明为指针防止拷贝出现问题吗? 别慌,先写个例子测测看 1234567891011121314151617181920212223242526...
Linux 图形化监控工具
最近在分析线上问题,需要监控 Linux 相关指标,如果只是用命令,总是只能知道当前的值,无法记录过程。而设备不是云厂商的设备,所以没有相关监控,zabbix 有,但是没有相关权限可以看到。所以找到一些好用的监控小方案。 nmon安装yum install nmon 使用 总结 安装方便,使用简单,最快速度能搞定,无需过多依赖,控制台展示 当然它还有其他内存等相关信息的展示 不是特别好看(毕竟是控制台要求也不能太高),精度相对低,只能有个大概峰值 bottom安装因为是 rust 搞的,所以可能有相关依赖,需要手动处理 12345678910111213141516wget https://github.com/ClementTsang/bottom/releases/download/0.4.5/bottom_x86_64-unknown-linux-gnu.tar.gztar xvf bottom_x86_64-unknown-linux-gnu.tar.gz./btm# 如果出现以下错误需要安装 glibc # /btm: /lib64/libc.so.6: vers...
你的网络还好吗
之前说了 CPU、内存 、IO 在排查过程中可能出现的问题以及出现问题会影响的指标,这次就来看看在 linux 中网络的问题。 在实际中我们遇到的最多的网络问题就是:不通!!!无论是 ping 不通,物理链路不通,还是 dns 解析有问题导致的不通,还是容器间网络访问网络隔离造成的不通,等等,这个问题总是由于部署上的环境导致的。还有一类比较烦的问题就是网络带宽本来就不高的情况下,大量的请求导致网络的拥塞,最明显的感受就是接口请求超时,各种超时,nginx 超时,请求本身超时等等。对于这些问题如何进行排查呢? 诊断指标sar命令sar -n DEV 1 12345678910[root@Linkin ~]# sar -n DEV 1Linux 3.10.0-1062.9.1.el7.x86_64 (Linkin) 07/04/2020 _x86_64_ (2 CPU)03:03:40 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s03:03:41 PM br...
你的 IO 还好吗
在 CPU 看来内存好慢啊,看我跑的多快;在内存看来磁盘你好慢啊,看我比你还快点;磁盘… IO 问题并非特别常见,但是因为最终要落到磁盘上,当它成为瓶颈时,往往会拖慢你的脚本,今天我们来分析下在 linux 中的 IO 问题 指标看 IO 并不只是看 IO,记住这句话,因为很多时候,IO 问题总会伴随着别的问题一起出现,而会导致误判的,从而遗漏了问题的关键。 IO 问题的指标来源于两块: 文件系统 磁盘 iowait命令top iostat %iowait 表示在一个采样周期内有百分之几的时间属于以下情况:CPU空闲、并且有仍未完成的I/O请求。 指标iowait 升高或者居高不下,可以考虑存在 IO 瓶颈或压力 rs / ws命令iostat -x -d 1 123Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %utilvda 0.00 ...
快速上手 dubbo-go
每次技术调研总会发现自己学不动了怎么办?用已有的知识来拓展要学习的新知识就好了~ by LinkinStar最近需要调研使用 dubbo,之前完全是 0 基础,对于 dubbo 只存在于听说,今天上手实战一把,告诉你如何快速用 go 上手 dubboPS:以下的学习方式适用于很多新技术 基本概念首先学习一个技术首先要看看它的整体架构和基本概念,每个技术都有着自己的名词解释和实现方式,如果文档齐全就简单很多。 http://dubbo.apache.org/zh-cn/docs/user/preface/background.html 大致浏览了背景、需求、架构之后基本上有一个大致概念 其实整体架构和很多微服务的架构都是类似的,就是有一个注册中心管理所有的服务列表,服务提供方先向注册中心注册,而消费方向注册中心请求服务列表,通过服务列表调用最终的服务。总的来说 dubbo 将整个过程封装在了里面,而作为使用者的我们来说更加关心业务实现,它帮我们做好了治理的工作。 然后我抓住了几个我想要知道的重点: 注册中心可替换,官方推荐的是 zk 如果有变更,注册中心将基于长连接推送...
你的内存还好吗
内存问题往往是线上环境最容易导致的问题,因为其实对于程序来说,内存总是不够用的。而大多数我们在线上遇到的问题总是一个叫 OOM 的,导致这个问题的原因也有很多,今天我们就来看看,如何在线上定位或者排查这样的问题。 诊断指标free命令free -h 1234[root@Linkin /]# free -htotal used free shared buff/cache availableMem: 7.6G 326M 6.2G 480K 1.1G 7.0GSwap: 0B 0B 0B 指标这个命令可以看到当前设备的内存总体使用情况,以及很清楚的看到交换区的内存使用情况 total:总内存 used: 已使用内存,包含共享内存 free: 未使用内存 shared: 共享内存 buff/cache 缓存和缓冲区 available 新进程可用内存 top命令top + M ...
Golang 监控全局变量
你是否曾经遇到过这样的情况,在开发环境排查问题,因为一些数据保存在了一些全局变量中,这些变量往往是一个 map 或者是一个数组,想看看在运行过程中,这里面究竟存放了什么数据,有时不得不在运行的时候将它输出到日志中,那么如果我想实时看到这些数据的情况又怎么办呢? 其实 golang 中已经存在这样的库,就是来做这个事情的 expvar 使用案例废话不多数,直接上案例 123456789101112131415161718192021222324252627282930313233343536373839package mainimport ( "expvar" "net/http")var ( s map[string]string user User)type User struct { Name string `json:"name"` Age int `json:"age"`}func showMap() interface{} {...
你的 CPU 还好吗
最近经常在线上排查一些问题,在大多数情况下,都是代码写的业务逻辑有问题;还有一些情况是内存上导致的问题,如 OOM 或者由于数据量大导致的一些问题;但是很少会关注,但常常又会瞟一眼的,这个关注点就是 CPU。 在说到 CPU 的时候往往除了 top 看一下 CPU 使用率之外,你还会关注别的什么吗?好像也不会。 但是其实当真正出现问题的时候,很多 CPU 相关的指标都会反映出一些问题,经过之前的学习今天就来总结记录一下。 诊断指标平均负载定义系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数(单位时间内活跃进程数) 查看 uptime top 指标当平均负载高于 CPU 数量的 70% 可能就有问题了(在实际中如果你看到平均负载突然升高,也就是三个值呈现递减的趋势,就需要考虑 CPU 问题了) CPU 使用率定义除了空闲时间外的其他时间占总 CPU 时间的百分比 查看 top ps mpstat -P ALL 5 pidstat 指标这个其实不用说你就有感觉的,如果你看到你的程序占用了 30%CPU 使用率,而别人都没得用,那就肯定奇怪了 上下文切...
python 基础语法笔记
记录python的一些基础语法,用于查阅 列表和元组 列表和元组都是有序的,可以存储任意数据类型的集合 列表是动态的,长度可变,存储空间和性能略逊与元组 元组是静态的,长度大小固定,不能增加修改 创建一个列表使用 empty_list = [] 相比于 list() 更好,因为 [] 底层走的c,而 list() 是函数,更加贵 1234567891011121314151617181920l = [1, 2, 3, 4]tup = (1, 2, 3, 4)list((1, 2, 3))[1, 2, 3]l.count(3)l.index(7)l.reverse()l.sort()l.append(4)# extend会将里面的元素添加进去,而append会直接将[1,2]作为一个元素加入l.extend([1,2])tuple([1, 2, 3])(1, 2, 3)tup.count(3)tup.index(7)list(reversed(tup))sorted(tup) 字典和集合本质就是hash表 删除会赋值为特殊值并在rehash调整大小的时候进行处理...
Golang用300行代码实现内网穿透
我们经常会遇到一个问题,如何将本机的服务暴露到公网上,让别人也可以访问。我们知道,在家上网的时候我们有一个 IP 地址,但是这个 IP 地址并不是一个公网的 IP 地址,别人无法通过一个 IP 地址访问到你的服务,所以在例如:微信接口调试、三方对接的时候,你必须将你的服务部署到一个公网的系统中去,这样太累了。 这个时候,内网穿透就出现了,它的作用就是即使你在家的服务,也能被其人访问到。 今天让我们来用一个最简单的案例学习一下如何用 go 来做一个最简单的内网穿透工具。 整体结构首先我们用几张图来说明一下我们是如何实现的,说清楚之后再来用代码实现一下。 当前网络情况 我们可以看到,画实线的是我们当前可以访问的,画虚线的是我们当前无法进行直接访问的。 我们现在有的路是: 用户主动访问公网服务器是可以的 内网主动访问公网服务也是可以的 当前我们要做的是想办法能让用户访问到内网服务,所以如果能做到公网服务访问到内网服务,那么用户就能间接访问到内网服务了。 想是这么想的,但是实际怎么做呢?用户访问不到内网服务,那我公网服务器同样访问不到吧。所以我们就需要利用现有的链路来完成这件事...
将版本信息打包到go的二进制中
很多时候对于go打包后的二进制文件,我们是无法知道这个二进制是什么当前什么版本、什么时候打包的,而很多软件的命令行都会有一个 -version 的选项来打印出当前程序的版本号,当然你可以直接在程序里面写死这个版本号,但是还有更加优雅的解决方式。 实现其实很简单,只需要在 build 的时候通过 -X 参数去指定变量值就可以了 1234567891011121314package mainimport "fmt"var ( Tag = "v0.0.0" CommitID = "" Branch = "" DATE = "")func main() { fmt.Println("tag:", Tag, "branch:", Branch, "commitID:", CommitID, "DATE:", DATE)} 123456789101...
回首网络知识之 TCP 协议
之前我们说了 UDP 协议,也说到了 UDP 协议和 TCP 协议的对比,知道了 TCP 协议有那么一些复杂,所以这次就来仔细说说这个复杂的 TCP 前言提到 TCP 你第一想到的应该就是两个字 “靠谱”~ 因为它的所有设计都是围绕着这个任务展开的。 报文格式 很多人一看到这个就头疼了,因为格式好复杂啊,和 UDP 对比起来,怎么多了那么多东西呢? 别急,其实并不是很多,而且只要你想着为什么,你就知道会有什么。 首先是两个端口,这个和 UDP 一样,肯定需要端口,不然的话不知道是发给谁的 然后是序号和确认序号,序号是为了解决乱序的问题,如果没有序号,那么我是不知道那个先那个后,同时我还要告诉对方我收到了这个序号的信息,所以需要一个确认序号,确认的方式是告诉你我要的下一个序号是多少 首部长度也很好理解,告诉你首部有多长,你就知道前面有多长,你才知道数据从哪里开始 中间那几个标识位需要知道的是: SYN:建立连接时用的,建立连接会标识为 1 ACK:回复你建立连接,建立连接之后标识为 1 RST:重新连接 FIN:结束连接 窗口大小,接收方告诉发送方别发太快了或者太慢了,...
Golang 之 WaitGroup 源码解析
如果我们有一个大的任务要做,我们会尝试将这个任务分解,分解完成之后并发交由 goroutine 去做,并且我需要当全部的任务完成之后再进行下面的步骤,在 sync 包下,就有这样一个东西适合上述情况,WaitGroup,今天我们来看看具体它是怎么实现的。 PS:在下面我统一用 wg 来简称 WaitGroup 使用它的使用非常简单,如下: 12345678910111213func main () { wg := sync.WaitGroup {} for i := 0; i < 10; i++ { wg.Add (1) go func (job int) { defer wg.Done () //do something fmt.Printf ("job % d done\n", job) }(i) } wg.Wait () fmt.Print...
回首网络知识之 UDP 协议
最近开始在恶补网络知识,算是一个复习,在学习了很多上层建筑之后回来看看之前的基础确实又有一个新的认识。一开始准备看完之后做一个整体的总结,但是发现知识点太多所以分了几期来写,每期都会短一点,这期我们先来简单了解一下 UDP 前言传输层中重要的两个协议 UDP 和 TCP ,在平时的时候,你虽然一直用着他们,但是往往感受不到他们的存在,他们两个往往经常会在面试的时候出现,打你一个措手不及。 在学习它之前,你首先要有一个概念,为什么我们需要 UDP 或者 TCP 这样的协议,它到底是在什么时候,什么地方,帮我们完成了什么样的事情? 在网络,我们研究的往往都是如何以一种合理的方式传递数据 而且协议则指定了这样的规定,当双方都遵守这样的规定,才能看懂互相说的话,才能达到合理传递数据的目的。 UDP 怎么样 UDP 格式简单,没有花里胡哨的东西 UDP 不会先探路,而是直接就发上了 UDP 不会管你卡不卡,发给你我就不管了 报文格式 源端口号(16 位,2 字节) 目的端口(16 位,2 字节) UDP 长度(16 位,2 字节) UDP 校验和(16 位,2 字节)...
实现分布式锁,你能想到什么?
所谓分布式锁,即在多个相同服务水平扩展时,对于同一资源,能稳定保证有且只有一个服务获得该资源 — by LinkinStar 其实对于分布式锁,也是属于那种看似简单,实则有很多细节的问题。很多人在被问到这个问题的时候,一上来就会说用redis嘛,setnx嘛,我知道我知道。但仅仅是这样就能搞定了吗?那么当我们在实现一个分布式锁的时候,我们究竟需要考虑些什么呢? 必考点首先作为一个分布式锁,你一定要保证的是什么呢? 不能有两个服务同时获取到一把锁(资源) 不能出现有一个资源一直被锁住(锁一直被持有) 我认为上面两点是必须要保证的,其他的点,比如锁的获取是否高效,锁获取的非阻塞等等是评价一个锁是否好用的点(当然也不是说不重要) 下面我们一个个实现方案来说,来看看究竟有多少细节是我们需要考虑的。 redis实现先从最普遍的实现方案开始说起,redis。利用redis的特性,nx,资源不存在时才能够成功执行 set 操作,同时设置过期时间用于防止死锁 加锁SET resource_key random_value NX PX lock-time 解锁DEL resource_k...
细说kubernetes - 初识deployment
当我们认识的k8s的时候,我们第一个认识的是pod,那么我觉得第二个认识的应该就是Deployment了。作为k8s中一个非常常见的对象,今天我们来看看它的实现原理和设计思想。 PS: 本文需要你对pod的定义和理解有一定的基础 定义在k8s中,对象常常都是以一个yaml格式的文件来定义的,deployment也不例外。如果你对k8s还不是特别了解,你大可以将一个文件看做是一个对象的所有属性,每个属性都有对应的值,其实也并不复杂。deployment的定义如下: 1234567891011121314151617181920212223242526# 定义版本apiVersion: apps/v1# 定义类型kind: Deployment# 定义名称和标签metadata: name: nginx-deployment labels: app: nginx# 定义规格spec: replicas: 2 selector: matchLabels: app: nginx # 定义模板 template: metadata: l...
细说kubernetes - 为什么是pod
k8s作为现在最火的容器编排调度平台,好用我也就不必多说了。当我们初识k8s的时候一个新的概念就到了我们眼前,那就是pod。我们在使用了之后也就渐渐的接受了pod这个东西,但是你有没有想过,为什么是pod?k8s为什么会有这样的设计?今天我们就来细细说说这个pod 架构图首先我们来回忆看看k8s的架构图是什么样子的这个是来源于 https://www.kubernetes.org.cn/ 中文官网的一个架构图 从架构图中我们可以看到,整个k8s的设计架构有以下几个要点: master、node架构;master就是大脑充当着管理者的角色 master中提供了api-server、controller-manager、scheduler、etcd用于管理node并向外提供服务 node就是实际干活的,提供了kubelet、proxy用于向master汇报情况,并管理pod的网络 而pod是k8s中最小的调度单位,Pod就是最小的,管理,创建,计划的最小单元. 当然其他组件都非常重要,这个我们以后再说,我们今天就来看看主角“pod” 为什么是pod?一开始用的时候我就好奇为什...
细说docker - 容器技术
docker对于现在的我们来说,已经是一个非常熟悉的东西了,docker无论是在部署打包,自动化,等方方面面都起着重要的作用,但是你是否有疑问,docker究竟是如何帮我们创建一个个隔离的环境的呢?今天我们就来看看,仔细说说docker PS: 以下的讨论都限定在linux环境下,在windows和macos下容器技术实现不相同,不在讨论范围内。 大方向为什么先要提到这个词呢?因为所有在操作系统上运行的程序都叫做进程。docker也不例外,从大的方向来讲,docker就是帮你创建了一个进程而已。而不一样的是,docker通过限制了各种环境,就像给这个进程画了一个圈,所以在这个进程本身看来,它自己好像被隔离了一般。 docker容器技术的核心,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界” 限制条件那么我们有了大方向,那么来细细看看,首先的第一个问题就来了,docker是通过什么方法对这个进程进行限制的呢? Namespace命名空间,没错就是它,是它限制了docker容器的环境。其实这是linux的一个功能而已,只不过没人想到docker会那它来做这个事情。...
再看golang垃圾回收
首先要说一些废话:之前我已经有博客写过golang的垃圾回收相关的内容,虽然很简略,但是涵盖了整体的流程,现在为啥又来写一遍呢?一方面有一些政治(你懂得)因素在里面,一方面最近又再研究。那么问题来了,那么多博客已经写过了它,我怎么把它讲出花来呢?我思前想后,于是想出了几个独特的角度来重新诠释一下golang的垃圾回收。 那首先如果再把整个gc过程简单说一遍,可能就没有人愿意听了,但是golang的gc说简单也简单说复杂其实也有很多细节,如何做到有自己的想法呢?于是我就强行举例了几个问题。 问题&角度在研究golang垃圾回收的时候,你有没有想过下面几个问题 golang如果有两个对象循环互相引用,是否会出现永远回收不了的对象? golang的gc标记方式为什么用bfs而不是dfs? 是否有可能永远不触发gc? 为什么golang的gc不整理、不分代? 个人理解首先说明一下,这些问题都是我自己想的,也没有什么所谓的正确答案,所以下面也是我的个人理解,如果有问题可以在下方留言进行讨论。 问题1 golang如果有两个对象循环互相引用,是否会出现永远回收不了的对象? ...
快速上手kubernetes——minikube最小实现
最近在研究k8s,就来写一个关于k8s快速上手,并记录采坑的点。需要的前置知识点:docker、k8s的一些基本概念,下面这个可能对你有帮助。https://juejin.im/post/5d1b2a656fb9a07edc0b7058 什么是k8s我们知道,我们可以将项目制作成docker镜像,然后利用docker去部署我们的项目,这样可以解决很多服务器环境所带来的问题;但是容器多了,容器与容器之间就需要访问,之间就需要网络配置等等,从而就有了docker-compose;但是当我们的服务进行升级,或者服务需要进行调度,扩容等等,这个时候就需要一个大管家来管所有的东西;这个大管家就是 - Kubernetes 初学会遇到的问题因为k8s的东西太多了,所以学习成本现在越来越高,好在k8s已经很多教程。我说一下现在学的时候肯定会遇到的大问题: 国内的问题(国内环境很多镜像拉不到) 本地搭建环境(原来搭建k8s需要一些服务器) 电脑环境的问题(windows和mac都有坑点) 最小实现现在我们就来在本机实现一个最小的k8s的实现,给出一个hello-worldk8s提供了mi...
快速上手terraform —— 阿里云OSS和ECS的创建
最近在研究terraform,采了一圈坑,记录一下。 什么是terraform?terraform 通过代码配置实现物理机等一些资源的分配。简单说就是,写一个配置文件,启动,就能帮你购买一台云的机器,或者说申请到oss的资源,或者是别的什么。具体功能见官网。 https://www.terraform.io/docs/index.html 名词解释:provider你可以把它看做各个厂商对terraform提供的插件,terraform可以调用这些插件从而实现对资源的操作管理。terraform流程:init -> plan -> apply -> destroy对应为:初始化,计划验证,实际应用,销毁 最小demo我将用一个最小的demo来演示它怎么干活的:通过terraform来创建一个阿里云的oss(以下没有利益相关)只是因为阿里云我有账号而已,其他供应商也有。 我的本地环境:macOS 步骤1 下载相关资源下载对应的客户端:https://www.terraform.io/downloads.html下载解压后得到:terraform的客户端,将它复...
golang中神奇的sync.Pool
在 golang 中有一个池,它特别神奇,你只要和它有个约定,你要什么它就给什么,你用完了还可以还回去,但是下次拿的时候呢,确不一定是你上次存的那个,这个池就是 sync.Pool 说实话第一次看到这个东西的时候,真的想不到这个东西有啥用啊,为什么要有这个东西呢?等我看完之后,嗯,还有有点用的;等到有一次优化经历的时候,嗯,这个有点意思了。今天我们就来看看这个神奇的 sync.Pool 简单案例首先我们来看看这个 sync.Pool 是如何使用的,其实非常的简单。它一共只有三个方法我们需要知道的:New、Put、Get 1234567891011121314151617181920package mainimport ( "fmt" "sync")var strPool = sync.Pool{ New: func() interface{} { return "test str" },}func main() ...
图解golang内存分配
我们知道所有程序运行都需要使用内存,而内存的管理和分配又是非常重要的,它决定了你的程序能不能在有限的资源内跑的更快。可以设想一下,如果你自己来设计的一个内存分配的规则,会遇到什么问题呢?如果你有了一大块内存你要怎么去合理的分配和使用呢?今天我们通过几张图来看看golang中的内存分配是怎样的。 前置知识:对golang的GPM模型有所了解,对GC有一定的了解,有助于你理解下面的内容。 想一想我们首先来想一下,如果我们自己来分配内存的时候可能会遇到什么问题。 我想要512G,你能给吗?操作系统的内存不是你想要多少就给你多少的。比如我跟操作系统说我要512G内存,你赶紧给我,不给我我就掐死你,如果你是操作系统,是不是立马就想把我给结束了? 能随便分割吗?如果我拿到一块内存,挺大的,你把它想象成一块地,我今天要用这块地的这个部分,肯定是从中间切一块出来用,然后明天要另一个部分,然后再切出来一部分。如果随便切,今天要一块三角形,明天要一块圆形,那么肯定会留有很多小块的地方,那些地方没有办法被合理的使用,就会浪费。等到想再要一块正方形的地的时候发现没地方可以切了。 不用了我需要放回去吗?...
大话图解gin源码
最近在网上搜了一下,对于gin框架用的人还是比较多的,我自己之前也在使用,但是对于源码解析这块,我没有看到自己想看到的那种从框架入手的解析图,所以嘿嘿嘿,我的机会就来了,今天就带来最完整的gin源码图解。希望通过这篇博客你也能自己学会拆轮子。 PS:本文建立在你已经能熟练使用gin的基础之上,如果还没用过可以去官网看一下:https://gin-gonic.com/zh-cn/docs/然后gin是对golang的http包的封装,所以最好对http包也要有了解。 整体分析逻辑先来说明一下我整体拆解的逻辑,对于一个框架,我喜欢从下面几个方面去入手拆解: 启动方式 如何使用 实现与特点针对于gin,我也将从这几个方面去入手,就会得到下面几个问题,带着问题看源码是必备条件。首先启动的时候gin做了些什么?gin封装了什么然后怎么去实现的?gin整体结构是怎么样的,有哪些结构?… 然后使用一个比较小的demo,然后先从方法入手,进源码看。 12345678910111213141516func main() { router := gin.Default() ...
图解goroutine调度
其实这个话题我早就想做了,奈何这个问题确实有点复杂,看了很多文章才有了一点点自己的理解。从golang一开始的使用我就已经开始好奇了,这个goroutine到底是怎么实现的呢?怎么就能搞出一个和线程类似,但是性能又那么好的东西的呢? 模型三个小伙子在看整体结构之前,我先来介绍三个小伙子,golang为了实现goroutine,定义了这样三个小伙子,让他们帮忙去实现。 G表示goroutine,存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等;另外G对象是可以重用的。 MM代表着真正的执行计算资源。在绑定有效的P后,进入调度器循环;而调度器循环的机制大致是从各种队列、P的本地队列中获取G,切换到G的执行栈上并执行G的函数,调用goexit做清理工作并回到M,如此反复。M并不保留G状态,这是G可以跨M调度的基础。 P表示逻辑processor,P的数量决定了系统内最大可并行的G的数量(前提:系统的物理cpu核数>=P的数量);P的最大作用还是其拥有的各种G对象队列、链表、一些cache和状态。 整体结构模型我们...
Golang的interface
由于golang中说interface的文章太多了,很多都已经说的很细节了,所以我再说感觉也有点难。于是总结出几个关键问题,供你参考,如果能做到准确无误有理有据的回答,那么interface应该是没有问题了。 问题 interface底层结构有哪两种,分别是什么样子的,里面保存了哪些信息? 其中tab是什么时候生成的? 从别的类型转换成interface,从interface转换成别的类型,这两者的过程是怎么样的? 两个interface之间是否可以比较? golang底层是如何判断一个类型是否实现了一个interface? 1、底层结构12345678910111213141516171819202122232425262728293031type eface struct { // 16 bytes on a 64bit arch _type *_type data unsafe.Pointer}type iface struct { // 16 bytes on a 64bit arch tab *itab d...
Golang之channel
go中的一个精髓就是就是channel,那么你有没有想过,它究竟是怎么实现的呢?我之前就怀疑过,是不是就是通过一个数组保存了一下传入的数据,然后在接收方读一读就完事了,那么阻塞又是怎么实现的呢?close的时候需要注意些什么呢? 结构首先我们来看一下channel的结构是怎么样的。 1234567891011121314151617181920type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elemtype *_type // element type sendx uint // send index recvx uint // receive inde...
你可能不知道的redis
以下是针对redis的知识点整理,用于复习,主要以罗列为主,详细具体讲解可以参考书《Redis设计与实现》,你可以过一遍看看有无知识点遗漏。个人能力有限,如果你还有补充可以再下方评论指出,万分感谢。 基础知识点 数据类型string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)底层实现包括:SDS动态字符串,双向链表,数组加链表,渐进式hash,跳表 redis是单线程 redis默认有16个数据库,默认先用0,可以使用select命令切换 过期策略惰性删除:当这个key被访问到,但是已经过期,那就删除定期删除:过一定时间,拿出一定的key判断,进行删除,如果超过一定数量,继续拿出一定的key进行判断删除,时间存在上限 内存超限当redis使用超过内存限制会根据策略来执行:noeviction:不能put,但是可以del和get,默认是这个策略volatile-lru:在有过期时间的key中,淘汰最少用的(redis是近似lru算法,会随机取几个淘汰最少用的)volatile-ttl:在有过期时间的key中,淘汰过期...
你可能不知道的mysql
以下是针对mysql的知识点整理,用于复习,主要以罗列为主,详细具体讲解可以参考书《高性能mysql》,你可以过一遍看看有无知识点遗漏。 执行sql过程客户端 -> 连接器 -> 分析器 -> 优化器 -> 执行器 -> 存储引擎连接器:连接上数据库,长连接分析器:分析语法(包含解析器和预处理器,解析器生成解析树,预处理器判断字段存在歧义)优化器:选择正确的索引进行优化执行执行器:执行具体sql返回结果 mysql的两个重要日志redo-log(重做日志):固定大小的循环缓存,InnoDB使用,即使重启,只要记录到了redo-log就不会丢失。防止mysql意外。bin-log:归档日志,所有sql都会记录,并且采用追加,满了之后新开,有两种方式,一种是记录sql语句(statement),一种是row,记录出现的事件。如果只记录sql语句会导致主从同步上面存在问题,从库执行相同的sql得到效果不同,所以还有一种混合的方式,mysql会自动判断当前语句是否会造成主从不同步的情况,如果会,那么就使用row记录如果不会就是用sql记录,因为row记录...



