Go 语言垃圾回收
极客时间《Go 语言从入门到实践》学习笔记 15,题图来自网络
50 | GC 友好的代码
如果不分配内存,就谈不上回收内存。
复杂对象尽量传递引用,避免内存复制开销。
从 benchmark 的结果来看,传值和传引用的对比非常明显。
51 | 高效字符串连接
fmt.Sprintf 也能连接字符串,很少用
Add + 最常用,但是性能也比较差,每次都要生成一个新的 string,原有的 string 需要 GC
StringBuilder 性能最好,1.10 版本之后推荐使用
bytes.Buffer 性能和 StringBuilder 差不多,1.10 版本之前使用
Java 或者 C# 里面也有 StringBuilder,名字类似,不知道底层实现是否一致。
有同学说要学习老师的 coding 方式和方法,我也同意,其实只要有 Benchmark Test,那么很多编程的想法和猜测,都可以自己写代码测试一下。
52 | 面向错误的设计
接受系统的不完美,接受自己和他人的不完美
面向错误的设计主要包括:隔离错误、冗余资源、限流、限时和断路器。
隔离错误,当系统中的一部分发生错误的时候,尽量减少对于系统其他部分的影响,尽可能让系统的主体保持正常操作,包括微内核架构和微服务部署。
要注意区分逻辑的重用和部署的隔离。
冗余一般有两种方式,Standby 和 Online Redundancy,其实也就是常说的一主一从和双机热备(读写分离?)
采用 token bucket 方式进行限流,避免集群中一部分机器故障导致的“雪崩”效应。
对所有的阻塞操作加上 timeout 限时,这个似乎是 go 语言的特长,避免资源耗尽。
搭配使用断路器和降级机制,在发生部分错误的时候保证系统整体或其他部分可用。
发现大家似乎都比较喜欢相对宏观的设计思想和具体的小技巧 tips。
53 | 面向恢复的设计
通过 http 的 ping 或者是看 进程是否存在,对于僵尸进程可能无法察觉,会得到不准确的健康状态。对于关键路径需要做有效的健康检查,激活一个检查程序。
这个检查程序感觉有点类似于在关键路径上做自动化的冒烟测试。
对于一些不明确的错误,如果只是记录日志而没有真正 Recover,僵尸进程驻留,而没有彻底解决,那么始终会存在隐患。
相对来说,不如直接让它 Crash,还记得当年重启 Wiindows 的经历么?
单体系统,所有的功能都集成在一起,当一部分功能发生错误的时候,没有办法单独重启出错的功能。
微服务,可以通过降级、重启等措施,是可以让出现错误的部分恢复。
有状态的可能需要考虑状态迁移,而无状态的可以用任何一个 instance 来替代,做到 instance flexible
与客户端协商,古老而有效的技术,类似 TCP 协议中的滑动窗口协议
在服务能力成为瓶颈的时候,定义一个返回码,告诉客户端慢一点发,或者告诉客户端隔一段时间再发,主动协调负载,让服务器从繁忙恢复。
断更了 11 天之后重新回来,就是为了 infoQ 的短袖
版权声明: 本文为 InfoQ 作者【escray】的原创文章。
原文链接:【http://xie.infoq.cn/article/03bba26514b98b885a4ff15c8】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论