Golang负载均衡
时间:2022-05-06
本文章向大家介绍Golang负载均衡,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
请求者向均衡服务发送请求
type Request struct {
fn func() int // The operation to perform.
c chan int // The channel to return the result.
}
注意这返回的通道是放在请求内部的。通道是first-class值
能很好的模拟一个请求者,一个负载产生者
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)
}
}
请求通道,加上一些负载记录数据
type Worker struct {
requests chan Request // work to do (buffered channel)
pending int // count of pending tasks
index int // index in the heap
}
均衡服务将请求发送给压力最小的worker
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。均衡服务跟踪请求待处理的数量来判断负载情况。
每个响应直接反馈给它的请求者。
定义负载均衡器
// 负载均衡器需要一个装很多worker的池子和一个通道来让请求者报告任务完成情况。
type Pool []*Worker
type Balancer struct {
pool Pool
done chan *Worker
}
负载均衡函数
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接口实现
// 使用堆来跟踪负载情况
func (p Pool) Less(i, j int) bool {
return p[i].pending < p[j].pending
}
Dispatch
// 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
// 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)
}
一个复杂的问题可以被拆分成容易理解的组件。它们可以被并发的处理。结果就是容易理解,高效,可扩展,好用。或许更加并行。
- 深入学习Apache Spark和TensorFlow
- 搭建 WPF 上的 UI 自动化测试框架
- ttf设置文字字体
- R语言构建追涨杀跌量化交易模型(附源代码)
- Apache Spark中使用DataFrame的统计和数学函数
- android进程 清理及activity栈管理
- 机器学习模型的变量评估和选择基于技术指标『深度解析』
- Picasso and Android-Universal-Image-Loader缓存框架
- 解决ListView嵌套ListView遇到的问题
- 《OEA - 实体扩展属性系统 - 设计方案说明书》
- webview与js的相互交互
- Java与js的交互
- Rafy 框架 - 流水号插件
- 产品前端重构(TypeScript、MVC框架设计)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android面试必备的JVM虚拟机制详解,看完之后简历上多一个技能!
- 如何在PHP中JSON在线解析
- Linux下如何克隆磁盘/分区命令dd入门
- Android自定义跑马灯文字效果
- Android实现图片自动切换功能(实例代码详解)
- Android Studio 3.6 正式版终于发布了,快来围观
- android使用ViewPager实现图片自动切换
- Android Studio 3.6 调试 smali的全过程
- Android 10 适配攻略小结
- Android P实现静默安装的方法示例(官方Demo)
- Android studio实现滑动开关
- Android实现TCP客户端支持读写操作
- Android通过命令连接wifi的方法(解决usb不能用问题)
- android studio使用SQLiteOpenHelper()建立数据库的方法
- Android自定义View绘制彩色圆弧