2018-09-30 AG

2018/09/26

每个月零零散散读了一些文章,前脚读,后脚忘,可能有些微收获,但还是感觉太过粗略,所以这里将一些读过的文章记录下来。

转瞬一想,既然可以记录文章阅读感想,何不也记录一下其他的一些东西,列如bug啦,算法啦,github项目啦等等之类的事情呢?

所以有这个ag,大概一周一次吧(可能以后这个ag会扩展)

文章

阿里如何实现100%容器化镜像化?八年技术演进之路回顾

阿里2011年的时候搞了一个T4,15年的时候引入docker的镜像机制(即将应用运行的环境一并打包),18年开源了PouchContainer 总的来说就是一个阿里的容器化演变的过程,有些段落有些重复 提问里面说的跨部门和跨子公司如何推广确实是一个好问题

聊聊Redis性能细节

使用一个软件,如果在高并发高流量的情况下,需要知道一些底层软件的原理,不能完全当一个黑盒使用 少用hash,少存储大数据,避免影响其他业务 使用配置中心,实现秒级降级

Go并发编程-Goroutine如何调度的?

注:这个文章被删除了

并发: 逻辑上具有处理多个同时性任务的能力 并行: 物理上同一时刻执行多个并发任务

goroutine说是协程不太恰当,因为goroutine是被多个线程调度执行的

Go调度器组成

Go语言虽然使用一个Go关键字即可实现并发编程,但Goroutine被调度到后端之后,具体的实现比较复杂。先看看调度器有哪几部分组成。

1、G

G是Goroutine的缩写,相当于操作系统中的进程控制块,在这里就是Goroutine的控制结构,是对Goroutine的抽象。其中包括执行的函数指令及参数;G保存的任务对象;线程上下文切换,现场保护和现场恢复需要的寄存器(SP、IP)等信息。

Go不同版本Goroutine默认栈大小不同。

2、M

M是一个线程或称为Machine,所有M是有线程栈的。如果不对该线程栈提供内存的话,系统会给该线程栈提供内存(不同操作系统提供的线程栈大小不同)。当指定了线程栈,则M.stack→G.stack,M的PC寄存器指向G提供的函数,然后去执行。

3、P

P(Processor)是一个抽象的概念,并不是真正的物理CPU。所以当P有任务时需要创建或者唤醒一个系统线程来执行它队列里的任务。所以P/M需要进行绑定,构成一个执行单元。

P决定了同时可以并发任务的数量,可通过GOMAXPROCS限制同时执行用户级任务的操作系统线程。可以通过runtime.GOMAXPROCS进行指定。在Go1.5之后GOMAXPROCS被默认设置可用的核数,而之前则默认为1。

Go调度器调度过程

首先创建一个G对象,G对象保存到P本地队列或者是全局队列。P此时去唤醒一个M。P继续执行它的执行序。M寻找是否有空闲的P,如果有则将该G对象移动到它本身。接下来M执行一个调度循环(调用G对象->执行->清理线程→继续找新的Goroutine执行)。

M执行过程中,随时会发生上下文切换。当发生上线文切换时,需要对执行现场进行保护,以便下次被调度执行时进行现场恢复。Go调度器M的栈保存在G对象上,只需要将M所需要的寄存器(SP、PC等)保存到G对象上就可以实现现场保护。当这些寄存器数据被保护起来,就随时可以做上下文切换了,在中断之前把现场保存起来。如果此时G任务还没有执行完,M可以将任务重新丢到P的任务队列,等待下一次被调度执行。当再次被调度执行时,M通过访问G的vdsoSP、vdsoPC寄存器进行现场恢复(从上次中断位置继续执行)。

1、P 队列 通过上图可以发现,P有两种队列:本地队列和全局队列。

2、上线文切换

简单理解为当时的环境即可,环境可以包括当时程序状态以及变量状态。例如线程切换的时候在内核会发生上下文切换,这里的上下文就包括了当时寄存器的值,把寄存器的值保存起来,等下次该线程又得到cpu时间的时候再恢复寄存器的值,这样线程才能正确运行。

对于代码中某个值说,上下文是指这个值所在的局部(全局)作用域对象。相对于进程而言,上下文就是进程执行时的环境,具体来说就是各个变量和数据,包括所有的寄存器变量、进程打开的文件、内存(堆栈)信息等。

3、线程清理 Goroutine被调度执行必须保证P/M进行绑定,所以线程清理只需要将P释放就可以实现线程的清理。什么时候P会释放,保证其它G可以被执行。P被释放主要有两种情况。

想养只猫 - 和菜头

给焦虑的生活带来一点点平静

浅谈Docker的安全性支持(上篇)

docker对于镜像内的系统做了一些安全方面的限制

Golang json 的进阶用法

go在解析json的时候,如果不确定一个字段的类型(如port是string还是int),可以定义一个新类型,然后实现接口:json.Unmarshaller interface / json.Marshaller interface,就可以将两个类型都hold住

go 101

有关go的一些tips知识点,挺好的,回头专门写个读后感

如何降低软件的复杂性? - 阮一峰

这篇文章是阮一峰看斯坦福大学计算机系教授John Ousterhout在谷歌的一次演讲(Youtube)和网上对该教授的一本新书《软件设计的哲学》(A Philosophy of Software Design)的书评的笔记 减少代码含义的模糊性 / 减少代码之间的依赖 将复杂的代码扔到一个模块 好的接口应该是小接口,大功能:也就是说对外暴露的方法比较少,但是在方法的内部实现上,可以很复杂,避免对外暴露复杂的细节

github

https://github.com/antlr/grammars-v4

使用ANTLR v4语法写的各个语言的语法

https://github.com/kocircuit/kocircuit

一个用go实现的并发的,general的但是类型安全的,函数式的语言 感觉比anko厉害点

https://github.com/Tencent/vConsole

一个手机网页端的类似chrome控制台console的console

https://github.com/dawnlabs/carbon

一个将代码生成美丽图片的工具

https://github.com/go101/go101

go 101的github源码