51CTO诚邀您9月23号和秒拍/国美/美团元专家一路聊智能CDN的优化之路,抓紧时光哦!
嗨,大年夜家好! 我的名字是Sergey Kamardin,我是Mail.Ru的工程师。
介绍
起首介绍我们的故事的高低文,应当介绍几点我们为什么须要这个办事器。
Mail.Ru有很多有状况的体系。 用户电子邮件存储是个中之一。 跟踪体系中的状况变更和体系事宜有几种办法。 这主如果经由过程按期体系轮询或关于其状况变更的体系通知。
两种方法都有利弊。 然则当涉及邮件时,用户收到新邮件的速度越快越好。
是以,为了削减办事器上的负载并加快邮件传递给用户,决定经由过程编写宣布-订阅办事器,一方面将接收有关状况更改的通知,另一方面则会收到这种通知的订阅。
先前
如今
第一个筹划显示了以前的样子。 浏览器按期轮询API,并萌芽有关Storage(邮箱办事)的更改。
第二个筹划描述了新架构。 浏览器与通知API建立WebSocket连接,通知API是Bus办事器的客户端。收到新的电子邮件后,Storage会向Bus(1)发送一条通知,由Bus发送到订阅┞愤。 API肯定连接以发送接收到的通知,并将其发送到用户的浏览器(3)。
所以今天我们将评论辩论API或WebSocket办事器。 我们的办事器将有大年夜约300万个在线连接。
实现方法
让我们看看若何应用Go函数实现办事器的某些部分,而无需任何优化。
- pool := gopool.New(128)
- poller.Start(conn, netpoll.EventRead, func() {
- // We will block poller wait loop when
- // all pool workers are busy.
- pool.Schedule(func() {
- Receive(ch)
- })
- })
在进行net/http ,我们来谈谈我们若何发送和吸法术据。 站在WebSocket协定(例如JSON对象) 之上的数据鄙人文中将被称为分组 。
我们开端实现包含经由过程WebSocket连接发送和接收这些数据包的Channel构造。
channel 构造
- // Packet represents application level data.
- type Packet struct {
- ...
- }
- // Channel wraps user connection.
- type Channel struct {
- conn net.Conn // WebSocket connection.
- send chan Packet // Outgoing packets queue.
- }
- func NewChannel(conn net.Conn) *Channel {
- c := &Channel{
- conn: conn,
- send: make(chan Packet, N),
- }
- go c.reader()
- go c.writer()
- return c
- }
所以在最多的时刻,我们的Channel.reader()和Channel.writer()正在等待接收或发送数据的处理。 每个都有4 KB的I/O缓冲区。