Go语言并发模式视角思考

犹记得2019年中旬进行知识点的学习和demo的练习,熟悉各种语法和并发调度的场景,

在2019年末开始参与项目实战开发和逻辑梳理

Go语言的接触也是更多探索和业务的拆件,做一些雏形工具,来慢慢的孵化业务生态

后来陆陆续续,在主营业务是PHP的情况下,尽量在业务脚本的倾向上使用Go语言,虽然前期两种语言的混合使用,总会导致写法冲突,但好在这个磨合期平稳度过。

后来也会将公司更多的业务倾向于Go来进行处理,比如新项目,或者老项目对并发要求高的项目会优先考虑。

罗列下Go语言的特点:

Go主要有静态语言、天生并发、内置GC、安全性高、语法简单、交叉编译和编译快速这几个方面的特性。

这些特性决定了Go的三个高富帅特性:运行快、开发快和部署快,而这些特性都是针对Google遇到的一些痛点来设计的。

优势

  • Go天生的自带并发调度,如协程和通道,且协程内存占用少,一个Goroutine栈空间最小2K
  • Go自带的格式统一,gofmt工具
  • Go语法的简洁,可读性强,严格语言规范
  • Go作为静态语言,编译效率高,性能相对高
  • Go跨平台的编译使用,跟操作shell命令一样的调用,部署方便,目前很多脚本都是这么来做的。
  • 丰富的内置类型,内置强大的工具
  • 内置runtime,自动垃圾回收机制

不足

  • 错误处理,会有错误难获取
  • 基于github获取代码库,会存在有代码库下架问题

Go适合做什么

  • 服务器编程,如:处理日志,数据打包,虚拟机处理,文件系统
  • 分布式系统,数据库代理器
  • 网络编程,如:Web应用、API应用、下载应用
  • 内存数据库
  • 云平台,Docker,Kubernetes等应用开发

GO语言的关键特性主要包括以下几方面:

  • 并发与协程
  • 基于消息传递的通信方式
  • 丰富实用的内置数据类型
  • 函数多返回值
  • defer机制
  • 反射(reflect)
  • 高性能HTTP Server
  • 工程管理
  • 编程规范

Go成功的项目

  • Go成功的项目nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息
  • docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建。
  • packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者
  • skynet:分布式调度框架
  • Doozer:分布式同步工具,类似ZooKeeper
  • Heka:mazila开源的日志处理系统
  • cbfs:couchbase开源的分布式文件系统
  • tsuru:开源的PAAS平台,和SAE实现的功能一模一样
  • groupcache:memcahe作者写的用于Google下载系统的缓存系统
  • god:类似redis的缓存系统,但是支持分布式和扩展性
  • gor:网络流量抓包和重放工具

码云上项目

接下来介绍下关于Go的并发相关的内容

Go 调度器实现机制

Go 调度器模型我们通常叫做G-P-M 模型,他包括 4 个重要结构,分别是G、P、M、Sched:

G:Goroutine,每个 Goroutine 对应一个 G 结构体,G 存储 Goroutine 的运行堆栈、状态以及任务函数,可重用。

G 并非执行体,每个 G 需要绑定到 P 才能被调度执行。

P: Processor,表示逻辑处理器,对 G 来说,P 相当于 CPU 核,G 只有绑定到 P 才能被调度。

对 M 来说,P 提供了相关的执行环境(Context),如内存分配状态(mcache),任务队列(G)等。

P 的数量决定了系统内最大可并行的 G 的数量(前提:物理 CPU 核数 >= P 的数量)。

P 的数量由用户设置的 GoMAXPROCS 决定,但是不论 GoMAXPROCS 设置为多大,P 的数量最大为 256。

M: Machine,OS 内核线程抽象,代表着真正执行计算的资源,在绑定有效的 P 后,进入 schedule 循环;

而 schedule 循环的机制大致是从 Global 队列、P 的 Local 队列以及 wait 队列中获取。

M 的数量是不定的,由 Go Runtime 调整,为了防止创建过多 OS 线程导致系统调度不过来,目前默认最大限制为 10000 个。

M 并不保留 G 状态,这是 G 可以跨 M 调度的基础。

Sched:Go 调度器,它维护有存储 M 和 G 的队列以及调度器的一些状态信息等。

调度器循环的机制大致是从各种队列、P 的本地队列中获取 G,切换到 G 的执行栈上并执行 G 的函数,调用 Goexit 做清理工作并回到 M,如此反复。

相关推荐
智驭未来掌门人6 分钟前
利用FFmpeg快速实现一个RTSP推流服务器
后端
程序员雷欧15 分钟前
AQS深度解析
开发语言·python
垚垚学技术_聚焦云原生19 分钟前
K8s Pod 完整生命周期详解
后端
JavaGuide23 分钟前
Github 史诗级故障,与此同时,Cursor 版「GitHub」正式上线!
前端·后端
不一样的少年_27 分钟前
修了 Bug、做了重构,为什么老板还是觉得你没产出?
前端·后端·程序员
水深火乐1 小时前
安全地生成验证码、密码和 Token
后端
小强19881 小时前
SQL Server 慢查询怎么定位?一套从“卡”到“快”的完整排查流程
后端
水深火乐1 小时前
interface和any
后端
步行cgn1 小时前
MyBatis Error evaluating expression ‘ids‘. Return value (3) was not iterable 错误详
java·后端
yujunl1 小时前
总结一下U9客开的成果
开发语言