返回顶部
首页 > 资讯 > 后端开发 > GO >golang 实现一个负载均衡案例(随机,轮训)
  • 827
分享到

golang 实现一个负载均衡案例(随机,轮训)

2024-04-02 19:04:59 827人浏览 八月长安
摘要

今天用Go实现一个简单的负载均衡的算法,虽然简单,还是要写一下。 1.首先就是服务器的信息 package balance type Instance struct {

今天用Go实现一个简单的负载均衡算法,虽然简单,还是要写一下。

1.首先就是服务器的信息


package balance
type Instance struct {
    host string
    port int
}
func NewInstance(host string, port int) *Instance {
    return &Instance{
        host: host,
        port: port,
    }
}
func (p *Instance) GetHost() string {
    return p.host
}
func (p *Instance) GetPort() int {
    return p.port
}

2.接着定义接口


package balance
type Balance interface {
    
    DoBalance([] *Instance,...string) (*Instance,error)
} 

3.接着,是实现接口,random.go


package balance
import (
    "errors"
    "math/rand"
)
func init()  {
    ReGISterBalance("random",&RandomBalance{})
}
type RandomBalance struct {
}
func (p *RandomBalance) DoBalance(insts [] *Instance,key...string) (inst *Instance, err error) {
    if len(insts) == 0 {
        err = errors.New("no instance")
        return
    }
    lens := len(insts)
    index := rand.Intn(lens)
    inst = insts[index]
    return
}

roundrobin.go


package balance
import (
    "errors"
)
func init() {
    RegisterBalance("round", &RoundRobinBalance{})
}
type RoundRobinBalance struct {
    curIndex int
}
func (p *RoundRobinBalance) DoBalance(insts [] *Instance, key ...string) (inst *Instance, err error) {
    if len(insts) == 0 {
        err = errors.New("no instance")
        return
    }
    lens := len(insts)
    if p.curIndex >= lens {
        p.curIndex = 0
    }
    inst = insts[p.curIndex]
    p.curIndex++
    return
}

4 然后,全部交给管理器来管理,这也是为什么上面的文件全部重写了init函数


package balance
import (
    "fmt"
)
type BalanceMgr struct {
    allBalance map[string]Balance
}
var mgr = BalanceMgr{
    allBalance: make(map[string]Balance),
}
func (p *BalanceMgr) registerBalance(name string, b Balance) {
    p.allBalance[name] = b
}
func RegisterBalance(name string, b Balance) {
    mgr.registerBalance(name, b)
}
func DoBalance(name string, insts []*Instance) (inst *Instance, err error) {
    balance, ok := mgr.allBalance[name]
    if !ok {
        err = fmt.Errorf("not fount %s", name)
        fmt.Println("not found ",name)
        return
    }
    inst, err = balance.DoBalance(insts)
    if err != nil {
        err = fmt.Errorf(" %s erros", name)
        return
    }
    return
}

下面进行测试


func main() {
    var insts []*balance.Instance
    for i := 0; i < 10; i++ {
        host := fmt.Sprintf("192.168.%d.%d", rand.Intn(255), rand.Intn(255))
        port, _ := strconv.Atoi(fmt.Sprintf("880%d", i))
        one := balance.NewInstance(host, port)
        insts = append(insts, one)
    }
    var name = "round"
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    for {
        inst, err := balance.DoBalance(name, insts)
        if err != nil {
            fmt.Println("do balance err")
            time.Sleep(time.Second)
            continue
        }
        fmt.Println(inst)
        time.Sleep(time.Second)
    }
}

5.如果想扩展这个,又不入侵原来的代码结构,可以类比上面实现dobalance接口即可


package add
import (
    "awesomeProject/test/balance"
    "fmt"
    "math/rand"
    "hash/crc32"
)
func init() {
    balance.RegisterBalance("hash", &HashBalance{})
}
type HashBalance struct {
    key string
}
func (p *HashBalance) DoBalance(insts [] *balance.Instance, key ...string) (inst *balance.Instance, err error) {
    defKey := fmt.Sprintf("%d", rand.Int())
    if len(key) > 0 {
        defKey = key[0]
    }
    lens := len(insts)
    if lens == 0 {
        err = fmt.Errorf("no balance")
        return
    }
    hashVal := crc32.Checksum([]byte(defKey), crc32.MakeTable(crc32.IEEE))
    index := int(hashVal) % lens
    inst = insts[index]
    return
}

这样就能交给管理器统一管理了,而且不会影响原来的api

补充:golang grpc配合nginx实现负载均衡

概述

grpc负载均衡有主要有进程内balance, 进程外balance, proxy 三种方式,本文叙述的是proxy方式,以前进程内的方式比较流行,靠etcd或者consul等服务发现来轮询,随机等方式实现负载均衡。

现在Nginx 1.13过后正式支持grpc, 由于nginx稳定,高并发量,功能强大,更难能可贵的是部署方便,并且不像进程内balance那样不同的语言要写不同的实现,因此我非常推崇这种方式。

nginx的配置

确认安装版本大于1.13的nginx后打开配置文件,写入如下配置


upstream lb{
#负载均衡的grpc服务器地址
  server 127.0.0.1:50052;
  server 127.0.0.1:50053;
  server 127.0.0.1:50054;
  #keepalive 500;#这个东西是nginx和rpc服务器群保持长连接的总数,设置可以提高效率,同时避免nginx到rpc服务器之间默认是短连接并发过后造成time_wait过多
}
server {
  listen       9527     Http2;
  access_log  /var/log/nginx/host.access.log  main;
  http2_max_requests 10000;#这里默认是1000,并发量上来会报错,因此设置大一点
  #grpc_Socket_keepalive on;#这个东西nginx1.5过后支持
  location / {
    grpc_pass grpc://lb;
    error_page 502 = /error502grpc;
  }
  location = /error502grpc {
    internal;
    default_type application/grpc;
    add_header grpc-status 14;
    add_header grpc-message "Unavailable";
    return 204;
  }
}

可以在host.access.log日志文件里面看到数据转发记录

proto文件:


syntax = "proto3"; // 指定proto版本
package grpctest;     // 指定包名
// 定义Hello服务
service Hello {
    // 定义SayHello方法
    rpc SayHello(HelloRequest) returns (HelloReply) {}
}
// HelloRequest 请求结构
message HelloRequest {
    string name = 1;
}
// HelloReply 响应结构
message HelloReply {
    string message = 1;
}

客户端:

客户端连接地址填写nginx的监听地址,相关代码如下:


package main
import (
 pb "protobuf/grpctest" // 引入proto包
 "golang.org/x/net/context"
 "google.golang.org/grpc"
 "google.golang.org/grpc/grpclog"
 "fmt"
 "time"
)
const (
 // Address gRPC服务地址
 Address = "127.0.0.1:9527"
)
func main() {
 // 连接
 conn, err := grpc.Dial(Address, grpc.WithInsecure())
 if err != nil {
  grpclog.Fatalln(err)
 }
 defer conn.Close()
 // 初始化客户端
 c := pb.NewHelloClient(conn)
 reqBody := new(pb.HelloRequest)
 reqBody.Name = "gRPC"
 // 调用方法
 for{
  r, err := c.SayHello(context.Background(), reqBody)
  if err != nil {
   grpclog.Fatalln(err)
  }
  fmt.Println(r.Message)
  time.Sleep(time.Second)
 }
}

服务端:


package main
import (
 "net"
 "fmt"
 pb "protobuf/grpctest" // 引入编译生成的包
 "golang.org/x/net/context"
 "google.golang.org/grpc"
 "google.golang.org/grpc/grpclog"
)
const (
 // Address gRPC服务地址
 Address = "127.0.0.1:50052"
 //Address = "127.0.0.1:50053"
 //Address = "127.0.0.1:50054"
)
var HelloService = helloService{}
type helloService struct{}
func (this helloService) SayHello(ctx context.Context,in *pb.HelloRequest)(*pb.HelloReply,error){
 resp := new(pb.HelloReply)
 resp.Message = Address+" hello"+in.Name+"."
 return resp,nil
}
func main(){
 listen,err:=net.Listen("tcp",Address)
 if err != nil{
  grpclog.Fatalf("failed to listen: %v", err)
 }
 s:=grpc.NewServer()
 pb.RegisterHelloServer(s,HelloService)
 grpclog.Println("Listen on " + Address)
 s.Serve(listen)
}

测试

以50052,50053,50054 3个端口启3个服务端进程,运行客户端代码,即可看见如下效果:

在这里插入图片描述

负载均衡完美实现, 打开日志文件,可以看到post的地址为 /grpctest.Hello/SayHello,nginx配置为所有请求都按默认 localtion / 转发,因此 nginx再配上合适的路由规则,还可实现更灵活转发,也可达到微服务注册的目的,非常方便。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。如有错误或未考虑完全的地方,望不吝赐教。

您可能感兴趣的文档:

--结束END--

本文标题: golang 实现一个负载均衡案例(随机,轮训)

本文链接: https://lsjlt.com/news/125024.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • golang 实现一个负载均衡案例(随机,轮训)
    今天用go实现一个简单的负载均衡的算法,虽然简单,还是要写一下。 1.首先就是服务器的信息 package balance type Instance struct { ...
    99+
    2024-04-02
  • Golang 实现简单随机负载均衡
    目录负载均衡简介随机负载均衡测试 随机负载均衡负载均衡简介 从设备角度实现负载均衡: 硬件负载均衡: 由专门的 负载均衡器 服务提供商,在你的服务器和外部网络之间架设 服务商的 负载...
    99+
    2024-04-02
  • Golang实现四种负载均衡的算法(随机,轮询等)
    随机负载 随机挑选目标服务器 package load_balance import ( "errors" "math/rand" ) //随机负载均衡 type Ran...
    99+
    2024-04-02
  • Golang加权轮询负载均衡的实现
    目录实现加权轮询负载均衡思路加权轮询负载均衡代码测试代码实现加权轮询负载均衡思路 代码实现一个加权负载均衡 Weight    &...
    99+
    2024-04-02
  • 怎么在golang中实现负载均衡
    本篇文章为大家展示了怎么在golang中实现负载均衡,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。golang的优点golang是一种编译语言,可以将代码编译为机器代码,编译后的二进制文件可以直接部...
    99+
    2023-06-14
  • Java负载均衡算法实现之轮询和加权轮询
    目录1.普通轮询算法2.加权轮询算法2.1.实现方式一2.2.实现方式二(重点难点)2.2.1.概述2.2.2.举个例子理解算法2.2.3.代码实现总结1.普通轮询算法 轮询(Rou...
    99+
    2024-04-02
  • nginx如何实现负载均衡轮询方式配置
    这篇文章主要介绍了nginx如何实现负载均衡轮询方式配置,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、概述Nginx的upstream目前支持的分配算法:1、round-...
    99+
    2023-06-29
  • Spring cloud alibaba之Ribbon负载均衡实现方案
    目录1.什么是Ribbon1.1客户端的负载均衡1.2服务器端的负载均衡1.3常见负载均衡算法2.Nacos使用Ribbon3.Ribbon负载均衡策略3.1常用负载均衡描述3.3修...
    99+
    2024-04-02
  • 实现高性能的Nginx负载均衡方案
    随着互联网的不断发展,对于系统的性能要求也越来越高。在处理大量的并发请求时,负载均衡是一种非常重要的解决方案,能够有效地分配请求的负载,提高系统的性能和可用性。而Nginx,作为一款高性能的Web服务器和反向代理服务器,被广泛应用于负载均衡...
    99+
    2023-10-21
    nginx 高性能 负载均衡
  • 服务发现与负载均衡机制Service实例创建
    目录什么是Service?创建一个Service实例集群外部访问svc创建代理外部应用的Service实例Service反代外部域名Service 的类型:什么是Service? S...
    99+
    2024-04-02
  • 多个服务器负载均衡怎么实现
    实现多个服务器负载均衡的方法有以下几种:1. 硬件负载均衡器:使用专门的硬件设备,如F5 BIG-IP等,将流量按照一定的算法(如轮...
    99+
    2023-09-07
    服务器 负载均衡
  • Nginx+Tomcat负载均衡集群的实现示例
    目录引言一、案例概述二、环境部署三、Nginx 主机安装四、Tomcat 安装及配置1. 安装 Tomcat2. Tomcat 服务器1配置3. Tomcat 服务器2配置五、Ngi...
    99+
    2024-04-02
  • 红帽 Piranha方案如何实现WEB负载均衡
    红帽 Piranha方案如何实现WEB负载均衡,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。系统环境: RHEL6.5x86_...
    99+
    2024-04-02
  • iis负载均衡高可用方案怎么实现
    IIS负载均衡高可用方案的实现主要包括以下几个步骤:1. 配置IIS服务器集群:搭建多台IIS服务器,将它们组成一个集群。2. 安装...
    99+
    2023-06-10
    iis负载均衡
  • Nginx使用ngx_http_upstream_module实现负载均衡功能示例
    目录负载均衡介绍什么是负载均衡为什么需要负载均衡负载均衡调度算法负载均衡后端节点状态负载均衡介绍 什么是负载均衡 负载均衡(Load Balance),意思是将负载(工作任务,访问请...
    99+
    2022-11-13
    Nginx 负载均衡 Nginx ngx_http_upstream_module
  • 使用Java实现5种负载均衡算法实例
    目录前言概念 几种负载均衡算法图例轮询算法 加权轮询法 加权随机法 随机法 IP_Hash算法 总结前言 负载均衡是为了解决并发情况下,多个请求访问,把请求通过提前约定好的规则转发给...
    99+
    2024-04-02
  • 使用Golang实现加权负载均衡算法的实现代码
    背景描述 如下图所示,负载均衡做为反向代理,将请求方的请求转发至后端的服务节点,实现服务的请求。 在nginx中可以通过upstream配置server时,设置weight表示对应...
    99+
    2024-04-02
  • nginx sticky实现基于cookie负载均衡示例详解
    目录前言思考1.cookie_jsessionid 负载均衡1.1 后端准备1.2 hash $cookie_jsessionid;配置2.nginx sticky 负载均衡2.1 ...
    99+
    2022-12-20
    nginx sticky cookie负载均衡 nginx sticky cookie
  • SpringCloud Zuul实现负载均衡和熔断机制方式
    一、场景 笔者就Zuul网关下实现其负载均衡与熔断机制(雪崩)进行实践,前提是已经导入zuul相关依赖 springboot版本:1.5.9.RELEASE springcloud版...
    99+
    2024-04-02
  • SpringCloud Zuul怎么实现负载均衡和熔断机制
    小编给大家分享一下SpringCloud Zuul怎么实现负载均衡和熔断机制,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、场景Zuul网关下实现其负载均衡与熔...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作