Go语言高并发实战:构建千万级在线的实时消息推送服务_第1页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第2页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第3页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第4页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Go 语言高并发实战构建千万级在线的实时消息推送服务2012.12.12关于我 张景埕,网名 diogin(/dadrn/) programmer360 Go 语言追随者与实践者 新浪微博:http:/ 摘要 一、为什么选用 Go 二、探究 Go 语言的实现细节 三、实时消息推送服务的特点 四、系统架构及组件细节 五、数据、经验和教训一、为什么选用 Go1. 高并发 一个 Go 进程可以轻易支撑几十万上百万并发运行的 Go 例程(只要你内存足够大) O(1) 的调度 5KiB/goroutine 的内存开销 net 包:pollServer (epoll/kqueue/iocp) 支持大量并发

2、连接 fd 的事件通知,同时还支持多核并行 (目前为 8 核) select/channel 提供卓越的例程间通信能力2. 高性能 编译为本地机器码 静态链接 (CGO_ENABLED=0) 轻量级的 runtime 实现 热点代码可以直接编写 C 或 ASM,同样静态链接进目标文件3. 垃圾收集 不想为内存泄露问题焦头烂额 朴素的实现:停顿式、标记 & 清除 还有很大的提升空间 资源泄露还得自己解决4. 低成本 学习成本低:源自 C 系,大量的 C 系程序员可以很快上手(这很重要) 运维成本低:不需要安装各种让人头疼的依赖,不需要搭建各种运行环境,部署非常方便5. 够用的标准库 ne

3、t encoding/gob strings, bytes, errors, strconv regexp os, time syscall sync .6. 高移植性 多种操作系统:Linux, FreeBSD, Darwin, NetBSD, OpenBSD, Windows 多种体系结构:386, amd64, arm(v5,v6,v7) 多种目标文件格式:elf/pe/macho7. 优秀的背景 Google, BSD License Ken Thompson, Rob Pike, Robert Griesemer, Russ Cox, Brad Fitzpatrick. 拥有强烈的

4、Plan 9 血统 C, Python 的风格Alternatives? Erlang Node.js D Rust二、探究 Go 语言的实现细节WHY? 产品级的应用,不是玩具 在国内(甚至国外),仍处于吃螃蟹阶段 我们需要能 hold 住可能出现的各种问题 提升团队成员技术水平 回馈 Go 本身,积极为其做贡献摘要 代码结构 逻辑结构 实现结构 程序启动 运行视角 深入 runtime1. 代码结构 工具 + 标准库 include/:Go 基本工具依赖的库的头文件 src/:Go 基本工具、标准库的实现 src/cmd/:Go 基本工具及其实现 src/lib*/:Go 基本工具依赖的库

5、的实现 src/pkg/:Go 标准库的实现2. 逻辑结构 gc (Go 编译器)、cc (Plan 9 C 编译器)、as (Plan 9 汇编器)、ld (Plan 9 链接器)、pack (Plan 9 目标文件归档工具) 工具链一条龙 支持多种操作系统、体系结构和可执行文件格式 程序 = N 个包的合并、组合 包 = const、var、type、func dist:引导程序,负责构建 Go 基本工具 go:管理 Go 的各项功能3. 实现结构 每个包里可以有 .go、.c、.s 文件,分别由 gc、cc、as 编译,最后统一用 ld/pack 链接并打包成静态链接库(遵循一致的 AB

6、I) 每个 Go 程序都包含最底层的 runtime 包,runtime 实现并封装了程序的运行时环境 syscall 包封装了操作系统调用,同时与 runtime 协作进行 goroutine 调度 sync 提供了基本的并发同步原语(工具包) reflect 为应用层代码提供运行时自省能力4. 程序启动 基本概念:M内核线程,Ggoroutine Go 使用符号“”分隔包与包内的成员名字 准备 runtimem0/runtimeg0 - 准备 argc, argv - 调度器初始化(内存初始化 - m 初始化 - 注册 args, envs - 设置并行参数) - 创建并运行 runtim

7、emain 例程(启动垃圾收集器 - maininit() - mainmain()5. 运行视角 程序由多个包构成,入口为 main 包,每个包在程序启动时按依赖顺序逐一初始化 程序内有多个 goroutine 并发运行,goroutine 通过 channel 进行同步/异步通信 自动化内存管理,不区分堆和栈6. 深入 runtime mgc0.c:垃圾收集器 proc.c:goroutine 管理及调度 hashmap.c:Go map chan.c:channel 实现 malloc.goc:内存分配器 asm_GOARCH.s:体系结构相关功能 iface.c:Go interfac

8、e symtab.c:符号表 cpuprof.c/mprof.goc:Profiling sys_GOOS.s:操作系统相关功能 thread_GOOS:内核线程统一抽象 panic:panic管理三、实时消息推送服务的特点摘要 长连接(多种接入协议:HTTP、TCP) 高并发(= 10,000,000) 多种发送方式(支持单播、多播、广播) 持久/非持久 准实时(200ms 2s) 客户端多样性(手机端、PC 端) 同一账号多客户端同时接入 接入网络频繁变化(电信、联通)1. 长连接 Server PUSH 的基础 HTTP Long Polling(Keep-Alive) 基于 TCP 的

9、自定义通信协议 采用心跳来侦测对方是否还在线2. 高并发 C10K? out 了,现在的标准是 C1000K 用户众多:各接入产品实时在线人数都在10,000,000 以上 Linux Kernel = 2.6.32, x86-64 sysctl -w fs.file-max=12000000 sysctl -w fs.nr_open=11000000 limit.conf: nofile=10000000 TCP/IP 协议栈参数调优3. 多种发送方式 点对点聊天(单播) 定点推送(多播) 全网推送(广播)4. 持久/非持久 持久消息必须保证不丢失 (需要离线存储) 非持久消息仅发给当前在线

10、用户5. 准实时 发一条消息,另一个人必须能很快收到 200ms 2s GC 卡顿会造成巨大麻烦6. 客户端多样性 手机、PC、平板电脑 不同的产品有不同的需求 提供机制,而非策略7. 同一账号多客户端接入 iMessage:iPhone, iPad, MacOSX QQ:PC、手机、平板、微信 互斥(早期 QQ)& 共存 策略:如何控制?8. 接入网络频繁变化 白天在电信,晚上在联通 一会儿在公司 wifi,一会儿 3G,一会儿 2G 断线,重连,断线,重连四、系统架构及实现细节摘要 逻辑架构:简单至上 组件:room 组件:register 组件:saver 组件:idgenera

11、tor 组件:center 存储:redis1. 逻辑架构:简单至上2. 组件:room 客户端所连接的进程,类似于一个聊天室 每个客户端一个 server goroutine 进行下推 每个 server 有一个 channel 存消息队列 room 内有 book 记录 user 与 server 映射 一个 http server 负责收消息并将消息路由到接收人所在的 room 和 server manager 负责掌控 room 的服务:内部单播、多播、广播 admin 负责 room 进程的管理3. 组件:register 由于 room 的分布式与全对称设计,需要有一个地方记录用户

12、当前连到了哪个 room,register 实现该角色 同时需要记录在线时长等信息 (业务需求) 本质上就是一个 key - value 的 map value 是个 struct hash 算法定位 register 进程 可以直接用 redis,但自己实现可以方便地添加业务逻辑4. 组件:saver 分布式全对称设计 提供存储接口,封装后端的分布式存储 接口采用 encoding/gob 编码格式的 rpc5. 组件:idgenerator 全局消息 id 生成器,int64 分布式,每个进程负责一块 id 区域 保证不重叠 后台 goroutine 每隔一秒写一次磁盘,记录当前 id 启

13、动时跳过一段 id,防止一秒内未写入磁盘的 id 重复生成6. 组件:center 提供消息操纵接口给应用服务器调用 运营人员后台发消息 - 应用服务器 - center - room - 客户端 RESTful API 有些任务(比如广播)需要一段时间,运营人员需要追踪发送进度,可能要临时停止,因此需要有“任务”概念,并可管理 提供统计接口7. 存储:redis 核心数据 db_users:ZSET,存各产品的用户集合 db_slots:LIST,存用户离线消息队列 db_buckets:DICT,存消息 id - 消息体五、数据、经验和教训数据 16台机器,标配24个硬件线程,64GB内存 Linux Kernel 2.6.32 x86_64 单机80万并发连接,load 0.20.4,CPU 总使用率 7%10%,内存占用20GB (res) 目前接入的产品约1280万在线用户 2分钟一次GC,停顿2秒 (1.0.3 的 GC 不给力,直接升级到 tip,再次

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论