March 28, 2020
mac下利用minikube安装Kubernetes环境
"本机为mac环境,安装有brew工具,所以为了方便这里直接使用brew来安装minikube工具。同时本机已经安装过VirtualBox虚拟机软件。\nminikube是一款专门用来创建k8s 集群的工具。\n一、安装minikube 参考 , 在安装minkube之前建议先了解一下minikube需要的环境。\n先安装一个虚拟化管理系统,如果还未安装,则在 HyperKit、VirtualBox 或 VMware Fusion 三个中任选一个即可,这里我选择了VirtualBox。 如果你想使用hyperkit的话,可以直接执行 brew install hyperkit 即可。\n对于支持的driver_name有效值参考, 目前docker尚处于实现阶段。\n$ brew install minikube 查看版本号\n$ minikube version minikube version: v1.8.2 commit: eb13446e786c9ef70cb0a9f85a633194e62396a1\n安装kubectl命令行工具\n$ brew install kubectl 二、启 …"
March 27, 2020
Golang中的限速器 time/rate
"在高并发的系统中,限流已作为必不可少的功能,而常见的限流算法有:计数器、滑动窗口、令牌桶、漏斗(漏桶)。其中滑动窗口算法、令牌桶和漏斗算法应用最为广泛。\n常见限流算法 这里不再对 计数器算法 和 滑动窗口 算法一一介绍,有兴趣的同学可以参考其它相关文章。\n漏斗算法 漏斗算法很容易理解,它就像有一个漏斗容器一样,漏斗上面一直往容器里倒水(请求),漏斗下方以固定速率一直流出(消费)。如果漏斗容器满的情况下,再倒入的水就会溢出,此时表示新的请求将被丢弃。可以看到这种算法在应对大的突发流量时,会造成部分请求弃用丢失。\n可以看出漏斗算法能强行限制数据的传输速率。漏斗算法\n令牌桶算法 从某种意义上来说,令牌算法是对漏斗算法的一种改进。对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发情况。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。\n令牌桶算法是指一个固定大小的桶,可以存放的令牌的最大个数也是固定的。此算法以一种固定速率不断的往桶中存放令牌,而每次请求调用前必须先从桶中获取令牌才可以。否则进行拒绝或等待,直到获取到有效令牌为止。如果桶内的令牌数量已达到桶的最 …"
March 19, 2020
Golang中的两个定时器 ticker 和 timer
"Golang中time包有两个定时器,分别为 ticker 和 timer。两者都可以实现定时功能,但各自都有自己的使用场景。\nTicker定时器 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func main() { // Ticker 包含一个通道字段C,每隔时间段 d 就向该通道发送当时系统时间。 // 它会调整时间间隔或者丢弃 tick 信息以适应反应慢的接收者。 // 如果d \u0026lt;= 0会触发panic。关闭该 Ticker 可以释放相关资源。 ticker1 := time.NewTicker(5 * time.Second) // 一定要调用Stop(),回收资源 defer ticker1.Stop() go func(t *time.Ticker) { for { // 每5秒中从chan t.C 中读取一次 \u0026lt;-t.C fmt.Println(\u0026#34;Ticker:\u0026#34;, time.Now().Format(\u0026#34;2006-01-02 15:04:05\u0026#34;)) } …"
March 4, 2020
认识虚拟内存
"什么是虚拟内存 虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。\n为什么需要虚拟内存 我们知道程序执行指令的时候,程序计数器是顺序地一条一条指令执行下去,这一条条指令就需要连续地存储在一起,所以就需要这块内存是连续的。物理内存是有限的,如果多个程序同时运行的话,访问同一个物理地址的话,就有可能内存地址冲突,怎么办呢?\n这时就需要虚拟内存发挥的作用了,程序里有指令和各种内存地址,系统从物理内存申请一段地址,与这个程序指令里用到的内存地址建立映射关系,这样实际程序指令执行的时候,会通过虚拟内存地址,找到对应的物理内存地址执行。对于任何一个程序来说,它看到的都是同样的内存地址。我们只需要维护一个虚拟内存到物理内存的映射表即可。\n这种从物理内存申请一段地址建立映射的方法,我们称其为内存分段。\n看似解决了上面的问题,但这里又引起了新的问 …"
January 18, 2020
Golang中关于defer语句理解的一道题
"示例 我们先看一下源代码\npackage main import \u0026#34;fmt\u0026#34; func f(n int) (r int) { defer func() { r += n recover() }() var fc func() defer fc() fc = func() { r += 2 } return n + 1 } func main() { fmt.Println(f(3)) } 大家感觉着打印的值是多少呢?5、9还是7?执行完以后发现是7。好像与多数理解的有些出入,为什么是7,而不是9呢。下面我们来分析一下。\n问题分析 对于defer执行的顺序是FIFO这一点都很清楚,我们只需要看搞懂f()函数的执行顺序就行了。\n执行顺序为:\n注册第1个defer 函数, 这里为匿名函数,函数体为 “func() { r += n recover() }()”,内部对应一个函数指针。这里延时函数所有相关的操作一步完成。 注册第2个defer函数,函数名为fc(),无函数体, 函数指针为nil(也有可能指针不会空,但指针指向的内容非函数体类型)。由于只是注册操作还未执行,所以并 …"
January 15, 2020
开发者必知redis知识点
"剖析Redis常用数据类型对应的数据结构 https://time.geekbang.org/column/article/79159\nredis中的COW(Copy-On-Write) https://www.jianshu.com/p/b2fb2ee5e3a0\nredis常用有哪些数据类型及每种数据类型的使用场景有哪些 https://www.cnblogs.com/tqlin/p/10478459.html\n如果存储一个JSON数据时,选择hash还是string 存储数据? https://segmentfault.com/a/1190000019552836\nredis与memcache的区别 https://www.cnblogs.com/JavaBlackHole/p/7726195.html https://blog.csdn.net/qq_34126805/article/details/81748107\nredis支持多CPU吗?如何发挥多cpu? https://blog.csdn.net/tanga842428/article/details/52641484 …"
January 14, 2020
golang中有关select的几个知识点
"golang中的select语句格式如下\nselect { case \u0026lt;-ch1: // 如果从 ch1 信道成功接收数据,则执行该分支代码 case ch2 \u0026lt;- 1: // 如果成功向 ch2 信道成功发送数据,则执行该分支代码 default: // 如果上面都没有成功,则进入 default 分支处理流程 } 可以看到select的语法结构有点类似于switch,但又有些不同。\nselect里的case后面并不带判断条件,而是一个信道的操作,不同于switch里的case,对于从其它语言转过来的开发者来说有些需要特别注意的地方。\ngolang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作。\n注:Go 语言的 select 语句借鉴自 Unix 的 select() 函数,在 Unix 中,可以通过调用 select() 函数来监控一系列的文件句柄,一旦其中一个文件句柄发生了 IO 动作,该 select() 调用就会被返回(C 语言中就是这么做的), …"
January 11, 2020
golang中的sync.Pool对象缓存
"参考文章 Golang 的 协程调度机制 与 GOMAXPROCS 性能调优 深入Golang之sync.Pool详解 golang sync.Pool 分析 [译] Go: 理解 Sync.Pool 的设计 视频 sync.pool对象缓存 知识点 Pool只是一个缓存,一个缓存,一个缓存。由于生命周期受GC的影响,一定不要用于数据库连接池这类的应用场景,它只是一个缓存。 golang1.13版本对 Pool 进行了优化,结构体添加了两个字段 victim 和 victimSize。 适应于通过复用,降低复杂对象的创建和GC代价的场景 因为init()的时候会注册一个PoolCleanup函数,他会在gc时清除掉sync.Pool中的所有的缓存的对象。所以每个sync.Pool的生命周期为两次GC中间时段才有效,可以手动进行gc操作 runtime.GC() 由于要保证协程安全,所以会有锁的开销 每个Pool都有一个私有池(协程安全)和共享池(协程不安全),其中私有池只有存放一个值。 每次Get()时会先从当前P的私有池private中获取( 类似MPG模型中的G) 如果获取失败,再 …"