Go语言高并发实战:构建千万级在线的实时消息推送服务

上传人:油条 文档编号:2665965 上传时间:2017-07-26 格式:PPT 页数:46 大小:178KB
返回 下载 相关 举报
Go语言高并发实战:构建千万级在线的实时消息推送服务_第1页
第1页 / 共46页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第2页
第2页 / 共46页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第3页
第3页 / 共46页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第4页
第4页 / 共46页
Go语言高并发实战:构建千万级在线的实时消息推送服务_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《Go语言高并发实战:构建千万级在线的实时消息推送服务》由会员分享,可在线阅读,更多相关《Go语言高并发实战:构建千万级在线的实时消息推送服务(46页珍藏版)》请在金锄头文库上搜索。

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

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

3、es, errors, strconvregexpos, timesyscallsync.,6. 高移植性,多种操作系统:Linux, FreeBSD, Darwin, NetBSD, OpenBSD, Windows多种体系结构:386, amd64, arm(v5,v6,v7)多种目标文件格式:elf/pe/macho,7. 优秀的背景,Google, BSD LicenseKen Thompson, Rob Pike, Robert Griesemer, Russ Cox, Brad Fitzpatrick.拥有强烈的 Plan 9 血统C, Python 的风格,Alternative

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

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

6、syscall 包封装了操作系统调用,同时与 runtime 协作进行 goroutine 调度sync 提供了基本的并发同步原语(工具包)reflect 为应用层代码提供运行时自省能力,4. 程序启动,基本概念:M内核线程,GgoroutineGo 使用符号“”分隔包与包内的成员名字准备 runtimem0/runtimeg0 - 准备 argc, argv - 调度器初始化(内存初始化 - m 初始化 - 注册 args, envs - 设置并行参数) - 创建并运行 runtimemain 例程(启动垃圾收集器 - maininit() - mainmain(),5. 运行视角,程序由多

7、个包构成,入口为 main 包,每个包在程序启动时按依赖顺序逐一初始化程序内有多个 goroutine 并发运行,goroutine 通过 channel 进行同步/异步通信自动化内存管理,不区分堆和栈,6. 深入 runtime,mgc0.c:垃圾收集器proc.c:goroutine 管理及调度hashmap.c:Go mapchan.c:channel 实现malloc.goc:内存分配器asm_GOARCH.s:体系结构相关功能,iface.c:Go interfacesymtab.c:符号表cpuprof.c/mprof.goc:Profilingsys_GOOS.s:操作系统相关功

8、能thread_GOOS:内核线程统一抽象panic:panic管理,三、实时消息推送服务的特点,摘要,长连接(多种接入协议:HTTP、TCP)高并发(= 10,000,000)多种发送方式(支持单播、多播、广播)持久/非持久准实时(200ms 2s)客户端多样性(手机端、PC 端)同一账号多客户端同时接入接入网络频繁变化(电信、联通),1. 长连接,Server PUSH 的基础HTTP Long Polling(Keep-Alive)基于 TCP 的自定义通信协议采用心跳来侦测对方是否还在线,2. 高并发,C10K? out 了,现在的标准是 C1000K用户众多:各接入产品实时在线人数都

9、在10,000,000 以上Linux Kernel = 2.6.32, x86-64sysctl -w fs.file-max=12000000sysctl -w fs.nr_open=11000000limit.conf: nofile=10000000TCP/IP 协议栈参数调优,3. 多种发送方式,点对点聊天(单播)定点推送(多播)全网推送(广播),4. 持久/非持久,持久消息必须保证不丢失 (需要离线存储)非持久消息仅发给当前在线用户,5. 准实时,发一条消息,另一个人必须能很快收到200ms 2sGC 卡顿会造成巨大麻烦,6. 客户端多样性,手机、PC、平板电脑不同的产品有不同的需

10、求提供机制,而非策略,7. 同一账号多客户端接入,iMessage:iPhone, iPad, MacOSXQQ:PC、手机、平板、微信互斥(早期 QQ)& 共存策略:如何控制?,8. 接入网络频繁变化,白天在电信,晚上在联通一会儿在公司 wifi,一会儿 3G,一会儿 2G断线,重连,断线,重连,四、系统架构及实现细节,摘要,逻辑架构:简单至上组件:room组件:register组件:saver组件:idgenerator组件:center存储:redis,1. 逻辑架构:简单至上,2. 组件:room,客户端所连接的进程,类似于一个聊天室每个客户端一个 server goroutine 进

11、行下推每个 server 有一个 channel 存消息队列room 内有 book 记录 user 与 server 映射一个 http server 负责收消息并将消息路由到接收人所在的 room 和 servermanager 负责掌控 room 的服务:内部单播、多播、广播admin 负责 room 进程的管理,3. 组件:register,由于 room 的分布式与全对称设计,需要有一个地方记录用户当前连到了哪个 room,register 实现该角色同时需要记录在线时长等信息 (业务需求)本质上就是一个 key - value 的 mapvalue 是个 structhash 算法

12、定位 register 进程可以直接用 redis,但自己实现可以方便地添加业务逻辑,4. 组件:saver,分布式全对称设计提供存储接口,封装后端的分布式存储接口采用 encoding/gob 编码格式的 rpc,5. 组件:idgenerator,全局消息 id 生成器,int64分布式,每个进程负责一块 id 区域保证不重叠后台 goroutine 每隔一秒写一次磁盘,记录当前 id启动时跳过一段 id,防止一秒内未写入磁盘的 id 重复生成,6. 组件:center,提供消息操纵接口给应用服务器调用运营人员后台发消息 - 应用服务器 - center - room - 客户端RESTf

13、ul 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,再次吃螃蟹)15亿个心跳包/天,占大多数持续运行一个月无异常,稳定,经验,敢于尝试新东西,勇于面对新挑战拿代码说话,拿数据说话不要凭感觉,要实际去测对一项新技术要切实了解其优势和劣势对于感觉模糊的地方,追查其实现,做到有备无患,教训,实时系统对 GC 非常敏感,幸好 tip 上提供了并行 GC,否则这就是一次惨痛教训,需要做架构方面的大调整 (将大进程拆分成小进程),Q & A,Thanks!,张景埕 http:/

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号