A non-dependent, online configuration, GO-developed, API gateway

GateKeeper Build Status Go Report Card Hex.pm GoDoc

GateKeeper 是一个 Go 编写的不依赖分布式数据库的 API 网关,使用它可以高效进行服务代理,支持在线化热更新服务配置 以及 纯文件方式服务配置,支持主动探测方式自动剔除故障节点以及手动方式关闭下游节点流量,还可以通过自定义中间件方式灵活拓展其他功能。

特性

  • httpwebsockettcp服务代理
  • 自动剔除故障节点
  • 手动关闭下游节点流量
  • 加权负载轮询
  • URL地址重写
  • 服务限流:支持独立IP限流
  • 高拓展性:支持自定义 请求前验证request方法请求后更改response方法tcp中间件http中间件 等。
  • 最少依赖:无需任何额外组件即可运行,mysqlredis 只做在线管理和统计使用可随时关闭。

内容

快速开始


安装GateKeeper之前,需要安装Go环境 (golang版本>=1.11), 如果需要界面管理则需要 mysqlredis支持。

  1. clone 代码到本地
git clone [email protected]:didichuxing/gatekeeper.git
  1. 开启 go mod 支持及代理支持
export GO111MODULE=on
export GOPROXY=https://goproxy.cn
  1. 创建 db 并导入数据

如果不使用在线服务接入以及统计功能,可以跳过本步。 默认使用:gatekeeper 作为数据库名

mysql -h localhost -u root -p -e "CREATE DATABASE gatekeeper DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"
mysql -h localhost -u root -p gatekeeper < install/db.sql --default-character-set=utf8
  1. 调整 mysqlredis 配置文件

修改 ./conf/dev/mysql.toml./conf/dev/redis.toml 为自己的环境配置。

如果不使用在线服务接入,删除 ./conf/dev/mysql.toml./conf/dev/redis.toml 即可。

  1. 运行代码
go run main.go
  1. 登陆管理后台

http://127.0.0.1:8081/admin/login

默认账号密码: admin / 123456

并发压测

压测条件:

  • 硬件: Xeon(R) CPU E5-2670 48 128G
  • 软件:centos 6.5wrk、下游服务golang 服务器无逻辑
  • 压测命令:./wrk -t并发数 -c连接数 -d30s url
并发量 链接数 压测时间 QPS 平均响应 CPU % MEM
100 1000 30s 26420.73 36.35ms 2560.1 417m
200 1000 30s 27972.51 35.45ms 2541 417m
200 2000 30s 29871.59 65.96ms 2630.5 358m
200 3000 30s 29626.71 105.81ms 2703.1 385m
200 4000 30s 30049.34 131.92ms 2710.9 410m
200 5000 30s 30650.13 161.50ms 2808.0 417m
200 10000 30s 29697.14 170.28ms 2780.3 476m
300 1000 30s 27407.33 33.10ms 2528.6 417m
400 1000 30s 26790.57 30.19ms 2401.3 417m
500 1000 30s 27812.94 38.94ms 2476.1 417m

使用手册

  • 集群配置及部署

    集群架构如图 image

    • 结合架构图对每个步骤说明如下:

      1. 用户通过接入层连接到 GateKeeper 实例中。
      2. 每个 GateKeeper 实例,针对每个服务模块,单独进行服务探测。
      3. 在线服务管理时,配置数据先保存到 GateKeeper 配置 DB 中,然后再通过调用配置更新接口( /reload ),更新所有实例机器配置。
    • 接入层一般选用 nginxHaproxyLVS

    nginx作为接入层为例,可根据网络需求确认是否暴露管理地址(/admin)。

          upstream gatekeeper { 
                server 10.90.80.16:8081; 
                server 10.90.80.17:8081; 
          }
          server {
              listen       8007;
              root         /home/webroot/official-website-api/;
              location ^~ /gatekeeper{
                      proxy_pass http://gatekeeper;
                      proxy_set_header Host $host;
                      proxy_set_header X-Real-IP $remote_addr;
                      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              }
          }
    
    • 配置集群

      通过修改 ./conf/dev/base.toml 中的 cluster 节点完成集群配置。

      • cluster_ip

      表示实际对外的访问地址,如果是域名填写域名。

      • cluster_addr

      http 服务需要监听的端口

      • cluster_list

      集群子机器 ip ,多 ip 以逗号分隔

    • 集群配置同步

      通过访问集群子机器的 /reload 接口确保所有代理机器配置统一。

在线管理接入

  • 管理登陆

    登陆账号密码在 ./conf/dev/admin.toml 中配置,使用以下地址登陆。

    http://127.0.0.1:8081/admin/login

  • 服务管理

    • 服务列表 image

      • 服务地址,如:http://10.90.164.31:8081/gatekeeper/test_http

      这里的 10.90.164.31:8081 表示集群地址,可以在 ./conf/dev/base.toml 中设置

      • QPS 集群当前QPS
      • QPD 集群当天总流量
      • NODE 当前可用节点数/总节点数
    • 新增、修改 http服务

      • 访问前缀设置,如:/gatekeeper/test_http

      这里的 /gatekeeper 是整个http对外路由的公共前缀。你可以在 ./conf/dev/base.toml中更改。

      • 探活地址,如:/pingurl重写对该地址无影响

      表示需要探测的目标服务器除去主机信息后的地址。若目标主机为: 10.90.164.31:8072,则真实地址为:http://10.90.164.31:8072/ping ,需要保证该地址访问可以正常返回200状态。

      • 重写规则:如:^/gatekeeper/test_http(.*) $1

      如果访问网关的地址是:http://127.0.0.1:8081/gatekeeper/test_http/ping, 则访目标的地址是: http://10.90.164.31:8072/ping, 如果不重写则访问目标的地址是: http://10.90.164.31:8072/gatekeeper/test_http/ping, 创建时如未填写则自动填写 ^访问前缀(.*) $1

      • 客户端IP限流

      表示单台网关实例当前服务最大允许QPS,0表示不限流。

    • 添加tcp服务:功能设置同http

    • 流量控制:可在针对某台目标机器进行流量关闭

  • 租户管理

    • 租户列表 image

      • 使用租户信息访问下游服务

      基于 app_idsecret 可以计算出签名 sign (为简化操作,我们这里直接使用 secret 作为了签名),然后直接使用get参数传入就可以访问下游服务了。 如: http://127.0.0.1:8081/gatekeeper/test_http/ping?app_id=test_app&sign=62fda0f2212eaffd90dbf04136768c5f

      • 租户鉴权

      参考下文中的 定义请求前验证 request 方法 service.AuthAppToken

      • 新增、修改租户

      接口列表,如:/gatekeeper/test_http。表示通过对应租户id,所有能请求到的接口的前缀。这样就可以起到限制某租户访问对应服务的功能了。目前租户只对http接口起作用。

      • 日请求总量

      表示目前租户,最多允许请求的总量

      • Qps限流

      表示当前租户最大允许QPS,0表示无限制

配置文件接入

  • 纯配置文件接入

    首先确保配置文件中不存在 mysql_map.tomlredis_map.toml, 否则配置会被重启覆盖。

    • 服务配置文件

    参照以下demo,编辑 ./conf/dev/module.toml

    # http服务示例,时间单位ms
    [[module]]
      [module.base]
        load_type = "http" #服务类型
        name = "test_http" #服务标识
        service_name = "test_http" #服务名称
    
      [[module.match_rule]]
        type = "url_prefix" #匹配类型
        rule = "/gatekeeper/test_http" #访问前缀
        url_rewrite = "^/gatekeeper/test_http(.*) $1" #重写规则
        
      [module.load_balance]
        check_method = "httpchk" #探测类型
        check_url = "/ping" #探测地址
        check_timeout = 2000 #探测超时时间
        check_interval = 5000 #探测频率
        type = "round-robin" #轮询类型
        ip_list = "10.90.164.31:8072,10.90.163.51:8072,10.90.163.52:8072,10.90.165.32:8072" #目标服务ip
        weight_list = "50,50,50,80" #目标权重
        forbid_list = "10.90.165.32:8072" #禁用目标ip
        proxy_connect_timeout = 10001 #连接目标服务器超时时间
        proxy_header_timeout = 10002 #获取header头超时
        max_idle_conn = 200 #连接最大空闲时间
        idle_conn_timeout = 10004 #最大空闲连接数
        
      [module.access_control]
        black_list = "" #ip黑名单
        white_list = "" #ip白名单
        white_host_name = "" #host白名单
        client_flow_limit = 0 #客户端IP限流
        open = 1 #访问权限(黑名单与白名单)控制是否打开 1为打开 0为关闭
    
    #tcp配置示例,时间单位ms
    [[module]]
      [module.base]
        load_type = "tcp" #服务类型
        name = "test_tcp" #服务标识
        service_name = "test_tcp" #服务名称
        frontend_addr = ":8900" #监听端口
    
      [module.load_balance]
        check_method = "tcpchk" #探测类型
        check_timeout = 2000 #探测超时时间
        check_interval = 5000 #探测频率
        type = "round-robin" #负载类型
        ip_list = "127.0.0.1:8018" #目标ip列表
        weight_list = "50" #目标权重列表
        forbid_list = "" #禁用ip列表
        proxy_connect_timeout = 10001 #连接超时时间
        
      [module.access_control]
        black_list = "" #黑名单
        white_list = "" #白名单
        white_host_name = "" #host白名单
        client_flow_limit = 0 #客户端ip限流
        open = 1 #访问权限(黑名单与白名单)控制是否打开 1为打开 0为关闭
    
    • 热加载服务配置
    sh ./reload.sh 8081
    

功能拓展

  • 定义请求前验证 request 方法 比如:租户权限验证方法
//AuthAppToken app的签名校验
func AuthAppToken(m *dao.GatewayModule, req *http.Request, res http.ResponseWriter) (bool,error) {
	ctx:=public.NewContext(res,req)
	//验证签名
	if err:=AuthAppSign(ctx);err!=nil {
		return false,err
	}
	//限速等操作
	if err := AfterAuthLimit(ctx); err != nil {
		return false,err
	}
	//todo 可以在这里加入sso跳转逻辑
	//ctx.Redirect("/sso/login",301)
	return true,nil
}

router.HttpServerRun() 运行之前调用注册函数

service.RegisterBeforeRequestAuthFunc(service.AuthAppToken)
  • 定义请求后修改 response 方法 比如:过滤返回中的城市数据函数
//定义数据修改方法
func FilterCityData(filterURLs []string) func(m *dao.GatewayModule, req *http.Request, res *http.Response) error{
	return func(m *dao.GatewayModule, req *http.Request, res *http.Response) error {
		//获取原始请求地址
		v:=req.Context().Value("request_url")
		requestURL,ok := v.(string)
		if !ok{
			requestURL = req.URL.Path
		}

		//获取请求内容
		payload, err := ioutil.ReadAll(res.Body)
		if err!=nil{
			return err
		}

		//验证是否匹配
		for _,matchURL:=range filterURLs{
			if matchURL==requestURL {
				//过滤规则
				filterData, err := filterJsonTreeByKey(string(payload),"data.list", "city_id", []string{"12"},)
				if err!=nil{
					return err
				}
				payload = []byte(filterData)
				break
			}
		}

		//重写请求内容
		res.Body = ioutil.NopCloser(bytes.NewBuffer(payload))
		res.ContentLength = int64(len(payload))
		res.Header.Set("Content-Length", strconv.FormatInt(int64(len(payload)), 10))
		return nil
	}
}

router.HttpServerRun() 运行之前调用注册函数

//注册内容更改函数
service.RegisterModifyResponseFunc(service.FilterCityData([]string{"/gatekeeper/tester_filter/goods_list"}))
  • 注册http中间件

    参照: ./middleware/http_limit.go

  • 注册tcp中间件

    参照: ./middleware/tcp_limit.go

测试

测试套件基于goconvey,所以需要确认安装了goconvey

  • 安装 goconvey
go get github.com/smartystreets/goconvey
  • 运行测试用例
cd tester
sh bootstrap.sh

License

gatekeeper is licensed under Apache License.

非常感谢以下项目对开源做出的贡献:

Owner
Similar Resources

REST API сервиса для просмотра видео роликов.

Go PostgreSQL О проекте Этот репозиторий представляет собой реализацию REST API сервиса для просмотра видео роликов. Используемы технологии Go Postgre

Dec 18, 2021

It's client library written in Golang for interacting with Linkedin Cruise Control using its HTTP API.

go-cruise-control It's client library (written in Golang) for interacting with Linkedin Cruise Control using its HTTP API. Supported Cruise Control ve

Jan 10, 2022

Fetch gas stations prices from Tankerkönig api with Orion Context Broker persistence

tankerkoenig-fuel-machinery - Fetch gas stations from tankerkoenig api and persist them into an Orion Context Broker Scope This project aims to fetch

Feb 14, 2022

protoc-gen-grpc-gateway-ts is a Typescript client generator for the grpc-gateway project. It generates idiomatic Typescript clients that connect the web frontend and golang backend fronted by grpc-gateway.

protoc-gen-grpc-gateway-ts protoc-gen-grpc-gateway-ts is a Typescript client generator for the grpc-gateway project. It generates idiomatic Typescript

Dec 19, 2022

A microservice gateway developed based on golang.With a variety of plug-ins which can be expanded by itself, plug and play. what's more,it can quickly help enterprises manage API services and improve the stability and security of API services.

A microservice gateway developed based on golang.With a variety of plug-ins which can be expanded by itself, plug and play. what's more,it can quickly help enterprises manage API services and improve the stability and security of API services.

Goku API gateway is a microservice gateway developed based on golang. It can achieve the purposes of high-performance HTTP API forwarding, multi tenant management, API access control, etc. it has a powerful custom plug-in system, which can be expanded by itself, and can quickly help enterprises manage API services and improve the stability and security of API services.

Dec 29, 2022

A fully-featured REST API developed in Golang for an online book store.

A fully-featured REST API developed in Golang for an online book store.

Oct 20, 2022

A fully-featured REST API developed in Golang for an online book store.

E-book Store A fully-featured REST API developed in Golang for an online book store. API Documentation Features Authentication (Sign up, Login and Res

Oct 20, 2022

Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance.

Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance.

Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance. RPC is usually heavy on processing logic and therefore cannot handle I/O serially. But Go's standard library net designed blocking I/O API, so that the RPC framework can only follow the One Conn One Goroutine design.

Jan 2, 2023

An online, full fledged bank system - ATM, online bank, transactions, bank cards

Bank An online, full fledged bank system - ATM, online bank, transactions, bank cards Online Bank: The online banking system can be used to send trans

Apr 2, 2022

The Durudex gateway combines all durudex services so that it can be used through a single gateway.

The Durudex gateway combines all durudex services so that it can be used through a single gateway.

Dec 13, 2022

Ruuvi-go-gateway - Software replica of the Ruuvi Gateway

ruuvi-go-gateway ruuvi-go-gateway is a software that tries to replicate Ruuvi Ga

Dec 21, 2022

Grpc-gateway-map-null - gRPC Gateway test using nullable values in map

Demonstrate gRPC gateway behavior with nullable values in maps Using grpc-gatewa

Jan 6, 2022

A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration

A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration

paddy 简介 paddy是一款单进程的独立运行的web server,基于golang的标准库net/http实现。 paddy提供以下功能: 直接配置http响应 目录文件服务器 proxy_pass代理 http反向代理 支持请求和响应插件 部署 编译 $ go build ./main/p

Oct 18, 2022

lambda-go-api-proxy makes it easy to port APIs written with Go frameworks such as Gin to AWS Lambda and Amazon API Gateway.

aws-lambda-go-api-proxy makes it easy to run Golang APIs written with frameworks such as Gin with AWS Lambda and Amazon API Gateway.

Jan 6, 2023

Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects

Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects

Couper Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects. Getting started The quick

Nov 18, 2022

Fully serverless CAPTCHA API created with API Gateway, Lambda, Dynamodb and Go

Fully serverless CAPTCHA API created with API Gateway, Lambda, Dynamodb and Go

Fully serverless CAPTCHA API created with API Gateway, Lambda, Dynamodb and Go

Mar 4, 2022

Dwarka - API gateway offers REST API to manage various device controlled using MQTT protocol

dwarka API gateway offers REST API to manage various device controlled using 'MQ

Sep 16, 2022

Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration, and automating updates to configuration when there is new code to deploy.

Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration, and automating updates to configuration when there is new code to deploy.

Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration (like Git repositories), and automating updates to configuration when there is new code to deploy.

Jan 8, 2023
Comments
  • 在10000并发的时候,出现以下错误

    在10000并发的时候,出现以下错误

    [ERROR][2019-12-27T09:14:49.186][log.go:74] _undef||func=module_proxy_errorhandler||err=dial tcp 192.168.212.87:8198: connectex: Only one usage of each socket address (protocol/network address/port) is normally permitted.||url=http://192.168.212.87:8198/ping||traceid=c0a8d4575e055b0913f83df8262c01b0||cspanid=||spanid=9ead8f5e53780187 能看下这问题

  • fix:bug

    fix:bug

    目前支持input、select、textarea,还差radio、checkbox、switch tcp无法填写问题

    服务统计没出来问题

    同步数据库信息到sql表

    校验规则全部删掉

    删掉鉴权策略、只留鉴权类型

    负载类型传英文,分别是random 随机、weight_round 权重轮询、consistent_hash 一致性hash、round 轮询

    服务域名和服务地址转为textarea多条换行即可

  • Bump github.com/gin-gonic/gin from 1.4.0 to 1.7.0

    Bump github.com/gin-gonic/gin from 1.4.0 to 1.7.0

    Bumps github.com/gin-gonic/gin from 1.4.0 to 1.7.0.

    Release notes

    Sourced from github.com/gin-gonic/gin's releases.

    Release v1.7.0

    BUGFIXES

    • fix compile error from #2572 (#2600)
    • fix: print headers without Authorization header on broken pipe (#2528)
    • fix(tree): reassign fullpath when register new node (#2366)

    ENHANCEMENTS

    • Support params and exact routes without creating conflicts (#2663)
    • chore: improve render string performance (#2365)
    • Sync route tree to httprouter latest code (#2368)
    • chore: rename getQueryCache/getFormCache to initQueryCache/initFormCa (#2375)
    • chore(performance): improve countParams (#2378)
    • Remove some functions that have the same effect as the bytes package (#2387)
    • update:SetMode function (#2321)
    • remove a unused type SecureJSONPrefix (#2391)
    • Add a redirect sample for POST method (#2389)
    • Add CustomRecovery builtin middleware (#2322)
    • binding: avoid 2038 problem on 32-bit architectures (#2450)
    • Prevent panic in Context.GetQuery() when there is no Request (#2412)
    • Add GetUint and GetUint64 method on gin.context (#2487)
    • update content-disposition header to MIME-style (#2512)
    • reduce allocs and improve the render WriteString (#2508)
    • implement ".Unwrap() error" on Error type (#2525) (#2526)
    • Allow bind with a map[string]string (#2484)
    • chore: update tree (#2371)
    • Support binding for slice/array obj [Rewrite] (#2302)
    • basic auth: fix timing oracle (#2609)
    • Add mixed param and non-param paths (port of httprouter#329) (#2663)
    • feat(engine): add trustedproxies and remoteIP (#2632)

    Improve performance

    ENHANCEMENTS

    • Improve performance: Change *sync.RWMutex to sync.RWMutex in context. #2351

    release v1.6.2

    Release Notes

    • BUGFIXES
      • fix missing initial sync.RWMutex (#2305)
    • ENHANCEMENTS
      • Add set samesite in cookie. (#2306)

    Contributors

    release v1.6.1

    ... (truncated)

    Changelog

    Sourced from github.com/gin-gonic/gin's changelog.

    Gin v1.7.0

    BUGFIXES

    • fix compile error from #2572 (#2600)
    • fix: print headers without Authorization header on broken pipe (#2528)
    • fix(tree): reassign fullpath when register new node (#2366)

    ENHANCEMENTS

    • Support params and exact routes without creating conflicts (#2663)
    • chore: improve render string performance (#2365)
    • Sync route tree to httprouter latest code (#2368)
    • chore: rename getQueryCache/getFormCache to initQueryCache/initFormCa (#2375)
    • chore(performance): improve countParams (#2378)
    • Remove some functions that have the same effect as the bytes package (#2387)
    • update:SetMode function (#2321)
    • remove a unused type SecureJSONPrefix (#2391)
    • Add a redirect sample for POST method (#2389)
    • Add CustomRecovery builtin middleware (#2322)
    • binding: avoid 2038 problem on 32-bit architectures (#2450)
    • Prevent panic in Context.GetQuery() when there is no Request (#2412)
    • Add GetUint and GetUint64 method on gin.context (#2487)
    • update content-disposition header to MIME-style (#2512)
    • reduce allocs and improve the render WriteString (#2508)
    • implement ".Unwrap() error" on Error type (#2525) (#2526)
    • Allow bind with a map[string]string (#2484)
    • chore: update tree (#2371)
    • Support binding for slice/array obj [Rewrite] (#2302)
    • basic auth: fix timing oracle (#2609)
    • Add mixed param and non-param paths (port of httprouter#329) (#2663)
    • feat(engine): add trustedproxies and remoteIP (#2632)

    Gin v1.6.3

    ENHANCEMENTS

    • Improve performance: Change *sync.RWMutex to sync.RWMutex in context. #2351

    Gin v1.6.2

    BUGFIXES

    • fix missing initial sync.RWMutex #2305

    ENHANCEMENTS

    • Add set samesite in cookie. #2306

    Gin v1.6.1

    BUGFIXES

    • Revert "fix accept incoming network connections" #2294

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

  • WeightRoundRobin算法 讨论一个问题

    WeightRoundRobin算法 讨论一个问题

    在看负载均衡算法 关于权重引入三个变量weight,currentWeight,effectiveWeight 这里请问effectiveWeight的作用是什么。其值与weight是完全相同,且不会更改的。 这个值是一个预留值吗?可以通过其他元素影响这个wrr算法?

    func (r *WeightRoundRobinStrategy) Next() string {
    	total := 0
    	var best *WeightNode
    	for i := 0; i < len(r.rss); i++ {
    		w := r.rss[i]
    		total += w.effectiveWeight
    		w.currentWeight += w.effectiveWeight
    		if w.effectiveWeight < w.weight {
    			w.effectiveWeight++
    		}
    		if best == nil || w.currentWeight > best.currentWeight {
    			best = w
    		}
    	}
    	if best == nil {
    		return ""
    	}
    	best.currentWeight -= total
    	return best.addr
    }
    
Related tags
Mizu - API traffic viewer for Kubernetes enabling you to view all API communication between microservices
Mizu - API traffic viewer for Kubernetes enabling you to view all API communication between microservices

The API Traffic Viewer for Kubernetes A simple-yet-powerful API traffic viewer f

Jan 9, 2023
Go (golang) bindings for the 0mq (zmq, zeromq) C API

NOTE: These gozmq bindings are in maintenance mode. Only critical bugs will be fixed. Henceforth I would suggest using @pebbe's actively maintained bi

Dec 9, 2022
🔥 A fast and beautiful command line tool to build API requests.
🔥 A fast and beautiful command line tool to build API requests.

Poodle A fast and beautiful command line tool to build API requests ?? Check out the full Demo! Poodle is an interactive command line tool to build an

Aug 23, 2022
Golang AMQP wrapper for RabbitMQ with better API

go-rabbitmq Golang AMQP wrapper for RabbitMQ with better API Table of Contents Background Features Usage Installation Connect to RabbitMQ Declare Queu

Dec 21, 2022
Insta API using Go and Mongodb
Insta API using Go and Mongodb

Insta-API HTTP JSON API that can be used to perform basic tasks of Creating User, Creating Post, Getting User & Post details through their Unique ID.

May 1, 2022
API for sending sms through the connected modem using golang

SMS sender API API for making SMS sending from modem, by sending post request to route Request for Send SMS url method 127.0.0.1:8000/api/v1/send-mode

Nov 5, 2021
App for test hypothesis about API for rabbitmq

REST API для работы с RabbitMQ Приложение для работы с брокером сообщений RabbitMQ через REST API. Основная мысль - что одиночные сообщения отправлять

Nov 12, 2021
Basic kick the tires on NATS Key-Value API (Go)

nats-kv-101 Basic kick the tires on NATS Key-Value API (Go) Usage # Get ./mybucket -s "nats://vbox1.tinghus.net" -creds "/home/todd/lab/nats-cluster1/

Feb 15, 2022
This API functionality for creating and retrieving users from the IDT backend
This API functionality for creating and retrieving users from the IDT backend

IDT Messaging Api This API functionality for creating and retrieving users from the IDT backend. The Go-Kit library which provides industry standard b

Dec 6, 2021
Golang Restful API Messaging using GORM ORM (MySQL) Gorilla Mux

Golang Restful API Messaging using GORM ORM (MySQL) Gorilla Mux Getting Started Folder Structure This is my folder structure under my $GOPATH or $HOME

Dec 14, 2021