
正文
go语言推送服务器 go 推送服务器
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
如何将用go语言开发的服务器程序部署到docker
部署简单。Go 编译生成的是一个静态可执行文件,除了 glibc 外没有其他外部依赖。这让部署变得异常方便:目标机器上只需要一个基础的系统和必要的管理、监控工具,完全不需要操心应用所需的各种包、库的依赖关系,大大减轻了维护的负担。这和 Python 有着巨大的区别。由于历史的原因,Python 的部署工具生态相当混乱【比如 setuptools, distutils, pip, buildout 的不同适用场合以及兼容性问题】。官方 PyPI 源又经常出问题,需要搭建私有镜像,而维护这个镜像又要花费不少时间和精力。
并发性好。Goroutine 和 channel 使得编写高并发的服务端软件变得相当容易,很多情况下完全不需要考虑锁机制以及由此带来的各种问题。单个 Go 应用也能有效的利用多个 CPU 核,并行执行的性能好。这和 Python 也是天壤之比。多线程和多进程的服务端程序编写起来并不简单,而且由于全局锁 GIL 的原因,多线程的 Python 程序并不能有效利用多核,只能用多进程的方式部署;如果用标准库里的 multiprocessing 包又会对监控和管理造成不少的挑战【我们用的 supervisor 管理进程,对 fork 支持不好】。部署 Python 应用的时候通常是每个 CPU 核部署一个应用,这会造成不少资源的浪费,比如假设某个 Python 应用启动后需要占用 100MB 内存,而服务器有 32 个 CPU 核,那么留一个核给系统、运行 31 个应用副本就要浪费 3GB 的内存资源。
良好的语言设计。从学术的角度讲 Go 语言其实非常平庸,不支持许多高级的语言特性;但从工程的角度讲,Go 的设计是非常优秀的:规范足够简单灵活,有其他语言基础的程序员都能迅速上手。更重要的是 Go 自带完善的工具链,大大提高了团队协作的一致性。比如 gofmt 自动排版 Go 代码,很大程度上杜绝了不同人写的代码排版风格不一致的问题。把编辑器配置成在编辑存档的时候自动运行 gofmt,这样在编写代码的时候可以随意摆放位置,存档的时候自动变成正确排版的代码。此外还有 gofix, govet 等非常有用的工具。
执行性能好。虽然不如 C 和 Java,但通常比原生 Python 应用还是高一个数量级的,适合编写一些瓶颈业务。内存占用也非常省。
相关问答
Q1: 基于go的websocket消息推送的集群实现
目前websocket技术已经很成熟,选型Go语言,当然是为了节省成本以及它强大的高并发性能。我使用的是第三方开源的websocket库即gorilla/websocket。
由于我们线上推送的量不小,推送后端需要部署多节点保持高可用,所以需要自己做集群,具体架构方案如图:
Auth Service:鉴权服务,根据Token验证用户权限。
Collect Service:消息采集服务,负责收集业务系统消息,存入MongoDB后,发送给消息分发服务。
Dispatch Service:消息分发服务,根据路由规则分发至对应消息推送服务节点上。
Push Service:消息推送服务,通过websocket将消息推送给用户。
集群推送的关键点在于,web端与服务端建立长连接之后,具体跟哪个推送节点保持长连接的,如果我们能够找到对应的连接节点,那么我们就可以将消息推送出去。下面讲解一下集群的大致流程:
1. web端用户登录之后,带上token与后端推送服务(Push Service)保持长连接。
2. 推送服务收到连接请求之后,携带token去鉴权服务(Auth Service)验证此token权限,并返回用户ID。
3. 把返回的用户ID与长连接存入本地缓存,保持用户ID与长连接绑定关系。
4. 再将用户ID与本推送节点IP存入redis,建立用户(即长连接)与节点绑定关系,并设置失效时间。
5. 采集服务(Collect Service)收集业务消息,首先存入mongodb,然后将消息透传给分发服务(Dispatch Service)。
6. 分发服务收到消息之后,根据消息体中的用户ID,从redis中获取对应的推送服务节点IP,然后转发给对应的推送节点。
7. 推送服务节点收到消息之后,根据用户ID,从本地缓存中取出对应的长连接,将消息推送给客户端。
其他注意事项:
Q2: golang socket通信 怎么把一个客户端发送的数据推送给其他客户端
Socket通信的原理还是比较简单的, 它大致分为以下几个步骤。 服务器端的步骤如下。 (1)建立服务器端的Socket,开始侦听整个网络中的连接请求。 (2)当检测到来自客户端的连接请求时,向客户端发送收到连接请求的信息,并建立与客户端之间的...
Q3: APNS推送Golang SDK使用Proxy代理
苹果go语言推送服务器的消息推送是通过请求域名: 实现的go语言推送服务器,该域名解析结果为美国,这引发go语言推送服务器了两个问题:
1、接口请求时间长,性能低,而且容易请求超时报错
2、高峰期推送请求错误率升高
总体思路:增加一个美国代理服务器,通过代理服务器请求苹果消息推送服务
1、原来流程
2、现在流程
3、具体方案实施选择
选择一:proxy服务器,部署一个正向代理服务,提供push消息的正向代理,消息通过代理服务器送达苹果服务端
选择二:proxy服务器,独立实现、部署一个 标准的apns服务,负责 ios消息推送。将需要走美国节点的请求转发到该proxy节点
具体情况、具体分析,应思考的点:
问题一、苹果官方提供的SDK中,不支持设置代理服务器。官方SDK不适合更改,对以后系统更新不利
问题二、只有苹果的push服务需要代理,其go语言推送服务器他例如华为、小米、vivo不应走海外代理
问题三、代理安全性
问题四、代理方案下,有重试逻辑。 如何准确定义和判断失败, 可能会引起消息重复推送
问题五、实现简单、有效,正向代理方式:只需实现一个实例化对象方法,其他利用原始sdk即可。独立apns服务方式:需要实现一个apns服务,国内、国外均需服务部署,需要增加独立的开发和运营成本,另外还得改造调用服务,实现请求调度,优点服务独立、单一,具备一个单独微服务条件
github.com/sideshow/apns2
方法一: 修改SDK文件
第一步:设置环境变量
第二步:修改apns2.NewClient方法
方法二: 从新定义一个NewClient方法
Q4: 为什么go语言适合开发网游服务器端
前段时间在golang-China读到这个贴:
个人觉得golang十分适合进行网游服务器端开发,写下这篇文章总结一下。
从网游的角度看:
要成功的运营一款网游,很大程度上依赖于玩家自发形成的社区。只有玩家自发形成一个稳定的生态系统,游戏才能持续下去,避免鬼城的出现。而这就需要多次大量导入用户,在同时在线用户量达到某个临界点的时候,才有可能完成。因此,多人同时在线十分有必要。
再来看网游的常见玩法,除了排行榜这类统计和数据汇总的功能外,基本没有需要大量CPU时间的应用。以前的项目里,即时战斗产生的各种伤害计算对CPU的消耗也不大。玩家要完成一次操作,需要通过客户端-服务器端-客户端这样一个来回,为了获得高响应速度,满足玩家体验,服务器端的处理也不能占用太多时间。所以,每次请求对应的CPU占用是比较小的。
网游的IO主要分两个方面,一个是网络IO,一个是磁盘IO。网络IO方面,可以分成美术资源的IO和游戏逻辑指令的IO,这里主要分析游戏逻辑的IO。游戏逻辑的IO跟CPU占用的情况相似,每次请求的字节数很小,但由于多人同时在线,因此并发数相当高。另外,地图信息的广播也会带来比较频繁的网络通信。磁盘IO方面,主要是游戏数据的保存。采用不同的数据库,会有比较大的区别。以前的项目里,就经历了从MySQL转向MongoDB这种内存数据库的过程,磁盘IO不再是瓶颈。总体来说,还是用内存做一级缓冲,避免大量小数据块读写的方案。
针对网游的这些特点,golang的语言特性十分适合开发游戏服务器端。
首先,go语言提供goroutine机制作为原生的并发机制。每个goroutine所需的内存很少,实际应用中可以启动大量的goroutine对并发连接进行响应。goroutine与gevent中的greenlet很相像,遇到IO阻塞的时候,调度器就会自动切换到另一个goroutine执行,保证CPU不会因为IO而发生等待。而goroutine与gevent相比,没有了python底层的GIL限制,就不需要利用多进程来榨取多核机器的性能了。通过设置最大线程数,可以控制go所启动的线程,每个线程执行一个goroutine,让CPU满负载运行。
同时,go语言为goroutine提供了独到的通信机制channel。channel发生读写的时候,也会挂起当前操作channel的goroutine,是一种同步阻塞通信。这样既达到了通信的目的,又实现同步,用CSP模型的观点看,并发模型就是通过一组进程和进程间的事件触发解决任务的。虽然说,主流的编程语言之间,只要是图灵完备的,他们就都能实现相同的功能。但go语言提供的这种协程间通信机制,十分优雅地揭示了协程通信的本质,避免了以往锁的显式使用带给程序员的心理负担,确是一大优势。进行网游开发的程序员,可以将游戏逻辑按照单线程阻塞式的写,不需要额外考虑线程调度的问题,以及线程间数据依赖的问题。因为,线程间的channel通信,已经表达了线程间的数据依赖关系了,而go的调度器会给予妥善的处理。
另外,go语言提供的gc机制,以及对指针的保护式使用,可以大大减轻程序员的开发压力,提高开发效率。
展望未来,我期待go语言社区能够提供更多的goroutine间的隔离机制。个人十分推崇erlang社区的脆崩哲学,推动应用发生预期外行为时,尽早崩溃,再fork出新进程处理新的请求。对于协程机制,需要由程序员保证执行的函数不会发生死循环,导致线程卡死。如果能够定制goroutine所执行函数的最大CPU执行时间,及所能使用的最大内存空间,对于提升系统的鲁棒性,大有裨益。
go语言推送服务器的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go 推送服务器、go语言推送服务器的信息别忘了在本站进行查找喔。






