channel使用
介绍 Go语⾔中,不要通过共享内存来通信,⽽要通过通信来实现内存共享。Go的 CSP(Communicating Sequential Process)并发模型,中⽂可以叫做通信顺序进程,是通过 goroutine 和 channel 来实现的。所以 channel 收发遵循先进先出 FIFO,分为有缓存和⽆缓存,channel 中⼤致有 buffer(当缓冲区⼤⼩部位0 时, 是个 ring buffer)、sendx 和 recvx 收发的位置(ring buffer 记录实现)、sendq、recvq 当前 channel 因为缓冲区不⾜⽽阻塞的队列、使⽤双向链表存储、还有⼀个 mutex 锁控制并发、其他原属等。 向channel写入数据和从channel里面读数据都是原子性的,所以channel是并发安全的。 channel的特性 给⼀个 nil channel 发送数据,造成永远阻塞 从⼀个 nil channel 接收数据,造成永远阻塞 给⼀个已经关闭的 channel 发送数据,引起 panic 从⼀个已经关闭的 channel...
yaml文件详解
一、yaml文件简介 Kubernetes只支持YAML和JSON格式创建资源对象,JSON格式用于接口之间消息的传递,适用于开发;YAML格式用于配置和管理,适用于云平台管理,YAML是一种简洁的非标记性语言。 1)yaml的语法规则: 大小写敏感 使用缩进表示层级关系 缩进时不允许使用Tal键,只允许使用空格 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可 ”#” 表示注释,从这个字符一直到行尾,都会被解析器忽略 注:- - - 为可选的分隔符 ,当需要在一个文件中定义多个结构的时候需要使用 2)在Kubernetes中,只需要知道两种结构类型即可: Lists Maps 2.1)YAML Maps Map顾名思义指的是字典,即一个Key:Value 的键值对信息。例如: 12apiVersion: v1kind: Pod 上述内容表示有两个键apiVersion和kind,分别对应的值为v1和Pod。 Maps的value既能够对应字符串也能够对应一个Maps。例如: 123456apiVersion: v1kind: Podmetadata: ...
SingleFlight
SingleFlight为什么我们需要 SingleFlight(使用场景)?一般情况下我们在写一写对外的服务的时候都会有一层 cache 作为缓存,用来减少底层数据库的压力,但是在遇到例如 redis 抖动或者其他情况可能会导致大量的 cache miss 出现。 如下图所示,可能存在来自桌面端和移动端的用户有 1000 的并发请求,他们都访问的获取文章列表的接口,获取前 20 条信息,如果这个时候我们服务直接去访问 redis 出现 cache miss 那么我们就会去请求 1000 次数据库,这时可能会给数据库带来较大的压力(这里的 1000 只是一个例子,实际上可能远大于这个值)导致我们的服务异常或者超时。这时候就可以使用 singleflight 库了,直译过来就是单飞,这个库的主要作用就是将一组相同的请求合并成一个请求,实际上只会去请求一次,然后对所有的请求返回相同的结果。如下图所示,使用 singleflight 之后,我们在一个请求的时间周期内实际上只会向底层的数据库发起一次请求大大减少对数据库的压力。 SingleFlight...
vim打造成ide
首先,介绍下环境: neovim,mac 插件管理vim-plugNeovimUnix, Linux12sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' Linux (Flatpak)12curl -fLo ~/.var/app/io.neovim.nvim/data/nvim/site/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim Windows (PowerShell)12iwr -useb...
io 多路复用
使用Go可以轻松地为每一个TCP连接创建一个协程去服务而不用担心性能问题,这是因为Go内部使用goroutine结合IO多路复用实现了一个“异步”的IO模型,这使得开发者不用过多的关注底层,而只需要按照需求编写上层业务逻辑。这种异步的IO是如何实现的呢?下面我会针对Linux系统进行分析。 在Unix/Linux系统下,一切皆文件,每条TCP连接对应了一个socket句柄,这个句柄也可以看做是一个文件,在socket上收发数据,相当于对一个文件进行读写,所以一个socket句柄,通常也用表示文件描述符fd来表示。可以进入/proc/PID/fd/查看进程占用的fd。 系统内核会为每个socket句柄分配一个读(接收)缓冲区和一个写(发送)缓冲区,发送数据就是在这个fd对应的写缓冲区上写数据,而接收数据就是在读缓冲区上读数据,当程序调用write或者send时,并不代表数据发送出去,仅仅是把数据拷贝到了写缓冲区,在时机恰当时候(积累到一定数量),会将数据发送到目的端。 Golang...
图解go语言内存分配
Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理。这样可以自主地实现更好的内存使用模式,比如内存池、预分配等等。这样,不会每次内存分配都需要进行系统调用。 Golang运行时的内存分配算法主要源自 Google 为 C 语言开发的TCMalloc算法,全称Thread-Caching...
go 类型转换
go类型转换go 存在 4 种类型转换分别为:断言、强制、显式、隐式。 通常说的类型转换是指断言,强制在日常不会使用到、显示是基本的类型转换、隐式使用到但是不会注意到。断言、强制、显式三类在 go 语法描述中均有说明,隐式是在日常使用过程中总结出来。 断言类型转换(针对接口)断言通过判断变量是否可以转换成某一个类型1var s = x.(T) 如果 x 不是 nil,且 x 可以转换成 T 类型,就会断言成功,返回 T 类型的变量 s。如果 T 不是接口类型,则要求 x 的类型就是 T,如果 T 是一个接口,要求 x 实现了 T 接口。 如果断言类型成立,则表达式返回值就是 T 类型的 x,如果断言失败就会触发 panic。 上述表所示再断言失败就会 panic,go 提供了另外一种带返回是否成立的断言语法: 1s, ok := x.(T) 该方法和第一种差不多一样,但是 ok 会返回是否断言成功不会出现 panic,ok 就表示是否是成功了。 类型switchgo语法还提供了一种类型switch的断言方法。 x 断言成了 type 类型,type 类型具体值就是...
client-go详解
client-go简介client-go是一个调用Kubernetes集群资源对象API的客户端,即通过client-go实现对Kubernetes集群中资源对象(包括deployment、service、ingress、replicaSet、pod、namespace、node等)的增删改查操作。大部分对Kubernetes进行前置API封装的二次开发都通过client-go这个第三方包来实现。 client-go目录结构12345678910111213.├── discovery # 定义DsicoveryClient客户端。作用是用于发现k8s所支持GVR(Group, Version, Resources)。├── dynamic # 定义DynamicClient客户端。可以用于访问k8s Resources(如: Pod, Deploy...),也可以访问用户自定义资源(即: CRD)。├── informers #...
面向对象设计原则
对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,**如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。**在面向对象设计中,可维护性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结构的设计水平。 **面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。**面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一。 原则的目的: 高内聚,低耦合 面向对象设计原则表 1,单一职责原则类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。 12345678910111213141516171819202122232425package mainimport "fmt"type ClothesShop struct {}func (cs *ClothesShop) OnShop()...
delayqueue的go简易实现
一、缘起很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。 例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。 一般来说怎么实现这类“48小时后自动评价为5星”需求呢? 常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价。 假设订单表的结构为:t_order(oid, finish_time, stars, status, …),更具体的,定时任务每隔一个小时会这么做一次: select oid from t_order where finish_time > 48hours and status=0; update t_order set stars=5 and status=1 where oid...