前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang负载均衡

Golang负载均衡

作者头像
李海彬
发布2018-03-28 11:23:12
9270
发布2018-03-28 11:23:12
举报
文章被收录于专栏:Golang语言社区Golang语言社区

请求者向均衡服务发送请求

代码语言:javascript
复制
type Request struct {
  fn func() int  // The operation to perform.
  c  chan int    // The channel to return the result.
}

注意这返回的通道是放在请求内部的。通道是first-class值

能很好的模拟一个请求者,一个负载产生者

代码语言:javascript
复制
func requester(work chan<- Request) {
  c := make(chan int)
  for {
      // Kill some time (fake load).
      Sleep(rand.Int63n(nWorker * 2 * Second))
      work <- Request{workFn, c} // send request
      result := <-c              // wait for answer
      furtherProcess(result)  
  }    
}

请求通道,加上一些负载记录数据

代码语言:javascript
复制
type Worker struct {
  requests chan Request // work to do (buffered channel)
  pending  int          // count of pending tasks
  index     int         // index in the heap
}

均衡服务将请求发送给压力最小的worker

代码语言:javascript
复制
func (w *Worker) work(done chan *Worker) {
  for {
      req := <-w.requests // get Request from balancer
      req.c <- req.fn()   // call fn and send result
      done <- w           // we've finished this request
  }
}

请求通道(w.requests)将请求提交给各个worker。均衡服务跟踪请求待处理的数量来判断负载情况。

每个响应直接反馈给它的请求者。

定义负载均衡器

代码语言:javascript
复制
// 负载均衡器需要一个装很多worker的池子和一个通道来让请求者报告任务完成情况。
type Pool []*Worker
type Balancer struct {
  pool Pool
  done chan *Worker
}

负载均衡函数

代码语言:javascript
复制
func (b *Balancer) balance(work chan Request) {
  for {
      select {
      case req := <-work: // received a Request...
          b.dispatch(req) // ...so send it to a Worker
      case w := <-b.done: // a worker has finished ...
          b.completed(w)  // ...so update its info
      }
  }
}

将负载均衡的池子用一个Heap接口实现

代码语言:javascript
复制
// 使用堆来跟踪负载情况
func (p Pool) Less(i, j int) bool {
  return p[i].pending < p[j].pending
}

Dispatch

代码语言:javascript
复制
// Send Request to worker
func (b *Balancer) dispatch(req Request) {
  // Grab the least loaded worker...
  w := heap.Pop(&b.pool).(*Worker)
  // ...send it the task.
  w.requests <- req
  // One more in its work queue.
  w.pending++
  // Put it into its place on the heap.
  heap.Push(&b.pool, w)
}

Completed

代码语言:javascript
复制
// Job is complete; update heap
func (b *Balancer) completed(w *Worker) {
  // One fewer in the queue.
  w.pending--
  // Remove it from heap.                  
  heap.Remove(&b.pool, w.index)
  // Put it into its place on the heap.
  heap.Push(&b.pool, w)
}

一个复杂的问题可以被拆分成容易理解的组件。它们可以被并发的处理。结果就是容易理解,高效,可扩展,好用。或许更加并行。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档