微服务的灾难-通用语言

在架构师们很喜欢的 Domain Driven Design,即 DDD 中,第一课就是教导团队形成自己独有的通用语言(Ubiquitous Language),作为业务概念沉淀下来。 作为非英语母语的国家,我们在日常交流中使用的是中文,在公司业务战略描述上使用的是中文,在高层进行任务拆分的时候使用的是中文,在领导安排工作的时候使用的是中文。唯独到了具体实现,即代码这一环节便变成了英文。当然这里我们不考虑有些公司会有汉语拼音这种尴尬的情况。 两种语言天生便有难以填平的鸿沟,在业务人员编写代码时,从中文到英文的转换,往往丢失一部分业务信息,产生一部分信息噪音,或者发生概念上的偏移。 英文语系的人对业务进行建模时,与业务方(领域专家)交流时,产生的概念和反馈可以直接落实到代码上,他们所使用的词汇不会发生变化。而其它语系的人就会在编写代码的时候发生概念偏移,比如我司是做打车业务,

流式计算中的分布式快照

流式计算系统是近些年发展较快的领域,虽然发展迅速,但实际上直到现在都没有能让所有人都满意的系统出现,哪怕是 flink/blink。 流式计算的理论基石是 leslie lamport 在 1985 年发表的论文《Distributed Snapshots: Determining Global States of a Distributed System》。首先将分布式系统中的进程定义为 process,然后将进程间的连接定义为 channel。当需要计算全局状态时,因为没有能够全局同步的时钟,所以需要有别的办法能够记录整个计算集群的状态值。 process 及连接 process 的 channel

一套实时特征系统的迭代过程

Gopher China 讲师尘埃落定,可惜今年没有获得去讲的机会,把之前的内容总结在 Blog 里吧~ 由于 MySQL 类带 Schema 类存储系统的设计问题,不支持快速的列扩充,实际业务中,一个业务实体的属性随着业务的发展是一定会膨胀的。这样持续在 MySQL 上加列往往就会捉襟见肘。比如我的历史业务订单表有 50 个字段,虽然会对历史数据进行归档,但在线上还是会有千万甚至亿级的数据,这时候在 MySQL 上加列一般使用 PTOSC 或者 Ghost 来改表,两者设计有区别,但缺点都一样:慢。

基于 Go 的内置 Parser 打造轻量级规则引擎

在公司内见到无数的人在前仆后继地造规则引擎,起因比较简单,drools 之类的东西是 Java 生态的东西,与 Go 血缘不合,商业规则引擎又大多超重量级,从零开始建设的系统使用起来有很高的学习成本。刚好可能也不是很想写 CRUD,几个人一拍即合,所以就又有了造轮子的师出之名。 要造一个规则引擎,说难实际上也不难。程序员们这时候捡起了学生时代的编译原理书,抄起递归下降、 lex/yacc 或者再先进一点的 antlr 之类的 parser generator 就搞了起来。造的时候说不定还发现噢噢,大多数 parser generator 还有不支持左递归的问题,然后按照它支持的文法写出的

2018 总结 && 2019 目标

2018 已经过去了,在 2018 年中的时候给自己定了 11 个目标:2018 目标,最优先的目标大部分也完成的差不多了,对 Go 源码的阅读工作量稍微有点低估(剩下一些查漏补缺的东西了)。。后来发现有位国外的兄弟也在干类似的事情,不过比我包装的更好:go-under-the-hood。虽有冲动把我的 Go 语言总结也慢慢向这种开源书的形式靠拢,不过想想,好像也没什么特别大的收益,暂时作罢。 18 年初阅读 Go 源码的时候,总算是把 Go 的反人类的 Plan9 汇编啃下来了,如果有条件的话,

在 ghost 中支持 mermaid

之前一直以为 ghost 支持不了 mermaid。。 最近看到某博主在 ghost 中加入了 mermaid 支持,研究了一下步骤,看起来和之前我加讨饭链接的方法差不多: code injection 在管理界面的 code injection 中增加 <script src="https://unpkg.com/mermaid@8.0.0/dist/mermaid.min.js"

几个 Go 系统可能遇到的锁问题

之前统一特征系统在 QA 同学的帮助下进行了一些压测,发现了一些问题,这些问题是较为通用的问题,发出来给其他同学参考一下,避免踩同样的坑。 底层依赖 sync.Pool 的场景 有一些开源库,为了优化性能,使用了官方提供的 sync.Pool,比如我们使用的 https://github.com/valyala/fasttemplate 这个库,每当你执行下面这样的代码的时候: template := "http://{{host}}/?q={{query}}&foo={{bar}

中台的末路

从 15 年开始,到 19 年现在为止。各大公司都在吹捧中台理念。仿佛中台是业务复杂性的救世主。是某些架构师和 PM 的新出路。各种割韭菜的讲中台的课程层出不穷。 当然,吹牛逼的时候大家都是拣好的说;苦逼的东西就只有内部人士知道,中台是靠谱还是不靠谱。只凭各路英雄的演讲内容,那看起来是靠谱的。 先来看看这些公开的观点: 中台是什么 阿里巴巴集团前端业务中公共、通用的业务沉淀到了这个事业部,包含了用户中心、商品中心、交易中心、评价等十几个中心,而共享业务事业部正是“厚平台”的真实体现,为阿里巴巴各种前端业务提供着相应服务中心领域内最为专业、稳定的业务服务。 钟华. 企业IT架构转型之道:

Go 系列文章 11: semaphore

后续更新和修正: https://github.com/cch123/golang-notes/blob/master/semaphore.md 数据结构 // Go 语言中暴露的 semaphore 实现 // 具体的用法是提供 sleep 和 wakeup 原语 // 以使其能够在其它同步原语中的竞争情况下使用 // 因此这里的 semaphore 和 Linux 中的 futex 目标是一致的 // 只不过语义上更简单一些 // // 也就是说,不要认为这些是信号量 // 把这里的东西看作 sleep

Go 系列文章 10: sync

原文和后续更新: https://github.com/cch123/golang-notes/blob/master/sync.md 线性一致性模型 从原理上来讲,atomic 操作和非 atomic 操作之间不满足线性一致性模型。这和现代计算机的 CPU 乱序执行,以及 compiler 为优化而进行的指令重排有关。在 C++ 中针对各种场景和性能需求提供了各种 memory order 选项: memory_order_relaxed Relaxed operation:

Go 1.9.2 的 bug

最近写了一段代码,精简一下大概是这样: type config struct { fk2Opts map[string]string } type doublebuffer struct { c1 config c2 config currentIdx int64 l sync.RWMutex } var option doublebuffer func readConfig(key string) bool { option.l.RLock() defer

松一口气

这周末终于把 《Go 高级编程》里我负责的章节写完了,松一口气。之前写的时候还是挺苦逼的,8 个月将近 20 篇内容,工作日休息日都在想要怎么系统化地去总结相关的知识。收获还是不少的。但是太苦了。一直在多线程思考 orz 顺利的话应该按部就班地半年内出版,最感谢的还是柴大这条大粗腿了,柴大好棒,能让我只靠 1/3 的内容就能让名字留在铅字资料上~ 当然了,因为自身以前这方面总结的资料不多,所以写出来的东西肯定还是或多或少有一些问题的,今年剩下的四个月,会继续对已经写完的东西做完善和补充,但肯定没有之前压力大了。 对于个人来说,通过这本书,把所有 web 领域相关的知识全部进行了梳理和总结(

Go 系列文章 9: slice

slice 和 array 要说 slice,那实在是太让人熟悉了,从功能上讲 slice 支持追加,按索引引用,按索引范围生成新的 slice,自动扩容等,和 C++ 或 Java 中的 Vector 有些类似,但也有一些区别。 不过 Go 里的 slice 还有一个底层数组的概念,这一点和其它语言不同。 runtime/slice.go type slice struct

Go 系列文章 8: select

原文地址: https://github.com/cch123/golang-notes 汗,写完这篇就发现 Go 目前的 master 分支上 select 的实现有所修改,比如文中的 hselect 结构体已经消失了。之后还是抽时间分析分析新版。。 select 本身是 Go 提供的一个语法糖,每次你写 select { } 的时候,实际上是相当于调用了一大堆函数。。只是 Go 的 runtime 内部帮你把这些复杂性屏蔽掉了。但是屏蔽也是有代价的,因为现在为止(

Go 系列文章 7: map

这次的 ascii 图太多了。。。粘到 blog 里毁灭性的不能看,所以还是看原文吧 orz https://github.com/cch123/golang-notes/blob/master/map.md

packt 出版的书吐槽

从办了双币信用卡开始买英文原版书以后,陆陆续续已经买了几十本了(看得完吗你。 嗯,其实大多数国外出版社的书质量还是可以的,比如 O'Reilly,NoStarch,Manning,Apress,微软之类的出版社。特别是 NoStarch,虽然每本书上面可能都有一条不明所以的彩边,而且封面以屎黄色(汗为主,不过感觉他们的封面设计的都挺好看的,比如下面这样的: 应该是有专门的封面设计师来做的吧。 manning 出版社的一般都是一些少数民族人物的绘作: 挺好看的。 O'Reilly 嘛,大家都熟悉,就是各种各样的动物书: Apress 相对就死板一些: 微软也差不多,沉闷的大公司风格: 唯独这个 Packt。。不知道该怎么吐槽了,

Go 系列文章6: syscall

系统调用 原文地址: https://github.com/cch123/golang-notes/blob/master/syscall.md 概念 一图胜千言: + - - - - - - - - - - - - - - - User Mode - - -

Go 系列文章5 : 定时器

去年和董大大聊过两句 Go 的定时器,当时大概看了眼代码是四叉堆,不过实现细节忽略掉了。 前几天和刘丁还有董大又聊起定时器的事情,正好就借这个机会把 Go 的定时器实现完整梳理一遍。不涉及 netpoll,因为我还没有看完这部分代码。 董大的文章网络和定时器怎么结合都提到了,感兴趣的可以看 这里。 看到两边有一样的图不要奇怪,所以这篇文章可以算联动吗,哈哈。 定时器算是服务端程序是非常重要的功能,特别是和网络或者文件系统打交道的系统,我们都会对每一次 IO 操作都加上合理的超时,以避免各种特定情况下的资源泄露。所以了解定时器的实现还是挺重要的。 PS: 看来 ghost 对 unicode 字符串组成的图支持也不是特别好,如果你觉得别扭,可以查看这篇文章的原文,

concurrency in go 读书笔记

《concurrency in go》这本书出版于 2017 年八月,里面有些观点还是蛮新颖的,烂大街的我就先不写了,重点写写书里提到的,我之前忽视的观点,以及一些奇技淫巧。 锁的粒度太大的话,有可能造成其它的 goroutine 饥饿 package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup

Go 系列文章4 : 调度器

推荐用 stackedit 导出后看,文章中有不少 mermaid 图表,ghost 博客不支持展示。原始的 markdown 保存在:这里 写得稍微有点乱,主要是按自己看代码的顺序来记录的,也不是出书,就这样吧。 PS: 新人不推荐刚学 Golang 就去看调度器代码,这部分代码个人觉得写得很乱。 调度 基本数据结构 goroutine 在 runtime 中的数据结构: // stack 描述的是 Go 的执行栈,下界和上界分别为 [lo,

2018 年的几个目标

18 年已经到 6 月份了,定目标可能有点太晚了,不过有总比没有强,作为一个硕士毕业已经工作四年的程序员,切实地感觉到了时间的重要性,需要按照规划来用,不能像年轻人那样挥霍了。 完成 Golang 的大部分源代码阅读,并完成 golang-notes 完成 redis 3.0 的源代码阅读并有总结产出 完成 nginx 的源代码阅读并有总结产出,这个坑遗留得有点久,14 年刚毕业的时候就挖了,汗 完成 nats 源码阅读并有总结产出 完成 Go 高级编程中

livelock

最近在看的 《concurrency in go》 里有这么一个例子: package main import ( "fmt" "sync" "sync/atomic" "time" ) func main() { cadence := sync.NewCond(&sync.Mutex{}) go func() { for range

blog 升级了。。

最近在写 golang-notes 的时候,看到 hexo 的 blog 支持直接展示 plantuml 和 mermaid 图表,折腾了一晚上发现并不是很好用。。。这些功能都是以插件形式支持,但在每个 blog 主题下又都需要自己配置,主题显然也没有什么统一的规范,自己用的话还是会碰到蛋疼的问题。此外 hexo 也不支持直接把图片上传到自己的 blog (别跟我说传什么七牛 cdn 之类的,几年后要是人挂了,你这就蛋疼了)。 虽然 ghost 已经商业化,且官网直接把 download

事故驱动开发

软件工程发展了这么多年,直到现如今,业界还是比较喜欢讨论 TDD,BDD,DDD。 虽然最后那个和前两个不太像是同一个维度的东西,不过因为都是 xDD,我们就先放在一起了嗯。每一种理论都有不少拥趸和践行者,都希望在各自的不归路上一路走到黑。至于每一种理论是否能为大众所接受,那就不好说了。犹记得某届 gopherchina,七牛的 CEO 去讲 http 测试,然后被人喷讲的太渣,没有深度,可能这位同学的潜台词是:我们想要的是画满了框图的架构 ppt,就是想看各种方块啊线条啊什么的,你却给我们来讲怎么写 test 和这些看起来 low 的不行的 test。

goroutine 的状态切换

在 runtime2.go(go 1.10) 中定义了 goroutine 生命周期中所有可能的状态,虽然状态不多,不过其状态切换的可能性还是蛮多的,整理了一张图: 带上 GC 以后,图会比较乱,去掉 GC 相关的状态切换以后,会清爽许多。这里所有的 goroutine 状态切换都是由 runtime 的函数触发的,我们把 runtime 字样也从图上删除: 抽时间写写状态切换的文章。 再来一张 p 状态切换的:

分布式系统中的不可靠复制问题

在《Designing Data-Intensive Application》一书中为当今大多数的互联网系统下了个定义,即数据密集型系统。在数据密集型系统中我们要应对的是数据的爆炸性增长问题。 为了应对问题我们采用了一些手段,比如 partition、replication,但这些手段,在一些场景或语言受限的情况下会带来一些麻烦的问题。本文主要讲一讲复制方面的问题。 说到复制 replication,可能大多数人第一印象都是存储系统中的复制,比如 MySQL 中基于 binlog 的复制,redis 中基于操作日志的复制,zk/etcd/kafka 中基于特定算法的复制(实质上也是基于 log 的复制),等等。但复制的概念本身实际上是很广的,

Go 系列文章3 :plan9 汇编入门

plan9 assembly 完全解析 众所周知,Go 使用了 Unix 老古董(误 们发明的 plan9 汇编。就算你对 x86 汇编有所了解,在 plan9 里还是有些许区别。说不定你在看代码的时候,偶然发现代码里的 SP 看起来是 SP,但它实际上不是 SP 的时候就抓狂了哈哈哈。 本文将对 plan9 汇编进行全面的介绍,同时解答你在接触 plan9 汇编时可能遇到的大部分问题。 本文所使用的平台是

[译]Go 和 interface 探究

这篇和之前的汇编那篇一样,都是翻译自 github 的 go-internals 这个项目,我的翻译地址是: https://github.com/cch123/go-internals 这篇写的比较长,如果讲深度的话。。那自己真是惭愧到不好意思去写 interface 的文章了。 不过还是要写,因为看这种基于汇编分析问题的东西,对于大多数人来说还是比较难。这篇其实也不能算面面俱到,而且作者的研究方法是从 binary asm 反推实现原理,实际上还可以直接去看编译器的代码的。 废话不多说,如下。 $ go version go version go1.

Go 系列文章2:Go 程序的启动流程

Bootstrap locate entry point 思路,找到二进制文件的 entry point,在 debugger 中确定代码位置。 使用 gdb: (gdb) info files Symbols from "/home/ubuntu/exec_file". Local exec file: `/home/ubuntu/exec_file', file type

Go 系列文章1:Channel 从使用到源码分析

说明,做 Go 开发也有不短的时间了,积累了不少工具,感觉是时候开这么个坑了。源码阅读这种事情,别人发文、出书是别人的事情,如果没有自己尝试做一遍始终还是会少得到很多东西。最近感觉时机成熟,因为自己没有之前那么菜了,所以开这个坑。慢慢填上。内容是读 1.10 的源代码。用 stackedit 写完以后同步到 github 上,这里是原始仓库:golang-notes。 更新主要还是在 github 吧,主要是一些流程图性质的东西,这个挫逼博客不能支持啊,汗。 Channel go
京ICP备15065353号-1