话说前几天我遇到了一个死锁问题,当时想了一些办法糊弄过去了,不过并没有搞明白问题的细节,周末想起来便继续研究了一下,最终便有了这篇文章。
作者归档:老王
在docker环境导入私有仓库的问题
最近我遇到了一个在 docker 环境导入私有仓库的问题:一个 Golang 项目,使用 gitlab ci 来发布,通过 gitlab runner 调用 docker-compose 来打包,但是在构建时失败了。
记又一次对Makefile的重构
我平常有一个习惯,就是不断看以前写的代码,想着有没有哪些方面可以改进,如果每天能把代码可读性量变 1%,那么日积月累就是质变:前些天我们写过一次对 Makefile 的重构,去掉了一处重复代码的坏味道,没过多久我便又发现了一处重复代码的坏味道,本文就让我们看看如何消灭它!
记一次对Makefile的重构
关于OCR项目的流水账
最近一直在开发某个 OCR 项目:底层用的是 ABBYY 提供的 FineReader 引擎,应用层把 FineReader 包装成 gRPC 对外提供服务,因为 FineReader 项目是 C++ 实现的,而我们团队使用的编程语言是 Golang,所以二者间通过 CGO 来完成交互。整个项目没有什么特殊的需求,只是鉴于 OCR 耗时较长,为了提升产品体验,要求在处理过程中:客户端可以主动退出;服务端能够实时返回已处理百分比。下面是根据需求画出来的流程图:
看上去很简单,不过我还是遇到不少问题,虽然这些问题主要都是一些细枝末节,基本上和 OCR 没什么关系,但是对别的项目还是会有所帮助的,下面让我一一道来。
浅谈K8S下gRPC负载均衡问题
一般来说,在 K8S 下部署服务是很简单的事儿,但是如果部署的是一个 gRPC 服务的话,那么稍不留神就可能掉坑里,个中缘由,且听我慢慢道来。
实战CGO
某项目要集成 PDF 文件的 OCR 功能,不过由于此功能技术难度太大,网络上找不到靠谱的开源实现,最终不得不选择 ABBYY FineReader Engine 的付费服务。可惜 ABBYY 只提供了 C++ 和 Java 两种编程语言的 SDK,而我们的项目采用的编程语言是 Golang,此时通常的集成方法是使用 C++ 或 Java 实现一个服务,然后在 Golang 项目里通过 RPC 调用服务,不过如此一来明显增加了系统的复杂度,好在 Golang 支持 CGO,让我们可以很方便的在 Golang 中使用 C 模块,本文总结了我在学习 CGO 过程中的心得体会。
浅谈pprof
对于大多数 Gopher 而言,一般平时最主要的工作内容除了实现各种无聊的业务逻辑之外,剩下的就是解决各种琐碎的问题。比如:查询性能瓶颈在哪里?查询内存泄漏在哪里?好在 pprof 是处理此类问题的利器,共有两套标准库,分别适用于不同的场景:
- runtime/pprof:采集工具型应用运行数据进行分析
- net/http/pprof:采集服务型应用运行时数据进行分析
命令行工具「go test」就包含了 runtime/pprof,相关参数请参考「go help testflag」:
shell> go test -cpuprofile cpu.out -memprofile mem.out -bench .
不过和 runtime/pprof 相比,更常用的是 net/http/pprof,接下来我们主要通过它来解决一些常见问题,想要激活 net/http/pprof 的话很简单,只要导入对应的包并启动服务即可:
import _ "net/http/pprof" func main() { _ = http.ListenAndServe("localhost:6060", nil) }
需要注意的是,千万别让外网访问到 pprof,否则可能会导致出现安全问题。有兴趣的读者可以尝试通过 google 搜索「intitle:/debug/pprof/ inurl:/debug/pprof/」看看反面例子。
浅谈NATS消息系统
浅谈微服务
虽说微服务早已是一个老生常谈的话题了,在 infoq 或者 thoughtworks 上可以找到很多案例,不过可惜的是其中相当比例的案例是失败的案例,究其原因,除了技术门槛之外,主要是因为很多人脱离了实际情况,只是为了微服务而微服务。本文通过一个例子带领大家从头到尾体验一下微服务的演化过程,不仅要做到知其然,更要做到知其所以然。