All Projects → wanghongfei → Gogate

wanghongfei / Gogate

Licence: mit
Go实现的高性能Spring Cloud网关(支持Consul和Eureka), 路由配置热更新、负载均衡、灰度、服务粒度的流量控制、服务粒度的流量统计

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Gogate

Spring Cloud Open Service Broker
Spring Cloud project for creating service brokers that conform to the Open Server Broker API specification
Stars: ✭ 140 (-24.73%)
Mutual labels:  spring-cloud
Spring Thrift Starter
Set of cool annotations that helps you building Thrift applications with Spring Boot
Stars: ✭ 151 (-18.82%)
Mutual labels:  spring-cloud
Event Sourcing Microservices Example
Learn about building microservices with event sourcing using Spring Boot and how to deploy a social network to Kubernetes using Docker Compose or Helm.
Stars: ✭ 167 (-10.22%)
Mutual labels:  spring-cloud
My Moments
Instagram Clone - Cloning Instagram for learning purpose
Stars: ✭ 140 (-24.73%)
Mutual labels:  spring-cloud
Spring Microservice Exam
硕果云,基于Spring Cloud搭建的新一代微服务教学管理平台,提供多租户、权限管理、考试、练习等功能,题型支持单选题、多选题、不定项选择题、判断题、简答题,二维码分享,移动端答题等
Stars: ✭ 146 (-21.51%)
Mutual labels:  spring-cloud
Tourist Lovers Sns
📍基于Spring Boot和Spring Cloud Alibaba的旅游爱好者社交小程序
Stars: ✭ 155 (-16.67%)
Mutual labels:  spring-cloud
Mi S
基于SpringBoot+SpringCloud+Mybatis主流框架搭建的分布式敏捷开发系统架构,为中、小型项目打造企业级基础开发多种解决方案。
Stars: ✭ 140 (-24.73%)
Mutual labels:  spring-cloud
Edc.springcloud.samples
Spring Cloud作为第二代微服务的代表性框架,已经在国内众多大中小型的公司有实际应用案例。许多公司的业务线全部拥抱Spring Cloud,部分公司选择部分拥抱Spring Cloud。此示例基于Spring Boot 1.5.x编写,展示了Spring Cloud的核心组件的基本使用方式,在学习Spring Cloud时可以参考本示例。
Stars: ✭ 183 (-1.61%)
Mutual labels:  spring-cloud
Grpc Spring Boot Starter
Spring Boot starter module for gRPC framework.
Stars: ✭ 2,190 (+1077.42%)
Mutual labels:  spring-cloud
Tesla
Tesla is a gateway service that provides dynamic routing,waf,support spring cloud,gRPC,DUBBO and more.
Stars: ✭ 161 (-13.44%)
Mutual labels:  spring-cloud
Cloud Book
《Spring Cloud 微服务架构进阶》各章节附录源码
Stars: ✭ 142 (-23.66%)
Mutual labels:  spring-cloud
Javadevjournal
Source code for the tutorials published on the Javadevjournal site.
Stars: ✭ 141 (-24.19%)
Mutual labels:  spring-cloud
Spring Cloud Dubbo Together
Spring Cloud与Dubbo共存方案
Stars: ✭ 155 (-16.67%)
Mutual labels:  spring-cloud
Spring Cloud Dataflow Ui
This repo provides the Dashboard application of Spring Cloud Data Flow
Stars: ✭ 140 (-24.73%)
Mutual labels:  spring-cloud
Spring Boot Cloud
基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目
Stars: ✭ 2,044 (+998.92%)
Mutual labels:  spring-cloud
Raincat
强一致分布式事务框架
Stars: ✭ 1,785 (+859.68%)
Mutual labels:  spring-cloud
Sctalk
基于spring cloud + Netty实现的聊天,兼容蘑菇街TeamTalk客户端,配合hazelcast提供消息服务器集群功能,同时支持socket和websocket.
Stars: ✭ 153 (-17.74%)
Mutual labels:  spring-cloud
Mcloud
基于Spring Cloud,实现微服务中常用的基础模块,包括 OAuth2 认证服务,统一注册中心,系统监控中心, 统一配置中心,API网关以及熔断器
Stars: ✭ 185 (-0.54%)
Mutual labels:  spring-cloud
Spring Cloud Tutorial
Spring Cloud Tutorial.《Spring Cloud 教程》
Stars: ✭ 173 (-6.99%)
Mutual labels:  spring-cloud
Spring Samples
A series of examples used to demonstrate certain features of Spring.
Stars: ✭ 154 (-17.2%)
Mutual labels:  spring-cloud

build

GoGate

Go语言实现的Spring Cloud网关,目标是性能,即使用更少的资源达到更高的QPS。

GoGate使用以高性能著称的FastHttp库收发HTTP请求,且会为每个host单独创建一个HostClient以减少锁竞争。

目前已经实现的功能有:

  • 基于Eureka(或Consul)服务发现的请求路由
  • 基于配置文件的请求路由
  • 请求路由、路由配置热更新
  • 负载均衡
  • 灰度发布(基于Eureka meta信息里的version字段分配流量)
  • 微服务粒度的QPS控制(有基于内存的令牌桶算法限流和Redis + Lua限流两种可选)
  • 微服务粒度的流量统计(暂时实现为记录日志到/tmp目录下)

初步测试了一下性能,结论如下:

相同的硬件环境、Zuul充分预热且关闭Hystrix的前提下,Go版的网关QPS为Zuul的2.3倍,同时内存占用仅为Zuul的十分之一(600M vs 50M)。而且Go基本上第一波请求就能达到最大QPS, zuul要预热几次才会稳定。

如果按消耗相同资源的前提下算的话,go一定要比zuul节省多的多的多的机器。同时,Gogate可以做到秒级启动, SpringBoot要等半天。

什么情况下可以考虑使用非Java语言的网关

  • 系统使用Spring Cloud全家桶
  • 对Zuul 1性能不满意
  • 对Cloud官方已经明确不会整合Zuul 2的行为不爽
  • 认为Spring Cloud Gateway不够成熟(相比Zuul 2.0)
  • 对网关的CPU/内存资源使用非常敏感

那么就可以考虑!

流程

arc

服务路由service-match-pre-filter: 根据URL匹配后端微服务

流量控制rate-limit-pre-filter: 令牌桶算法控制qps

URL重写url-rewrite-pre-filter: 调整向后端服务发请求的URL

转发请求: 负载均衡、按比例分配流量

gogate没有提供默认的Post Filter,可根据需要自己实现相应函数。

构建

go版本>=1.13。

在$GOPATH之外的任意目录下clone项目:

git clone https://github.com/wanghongfei/gogate

安装依赖:

go mod tidy

最后构建:

go build

使用

可以编译main.go直接生成可执行文件,也可以当一个库来使用。

可以在转发请求之前和之后添加自定义Filter来添加自定义逻辑。

详见examples/usage.go

路由配置

路由匹配规则:

  • id不为空时,会使用eureka的注册信息查询此服务的地址
  • host不为空时, 会优先使用此字段指定的服务地址, 多个地址用逗号分隔
  • 使用Trie Tree进行前缀匹配。

当路由配置文件发生变动时,访问

GET /_mgr/reload

即可应用新配置。

示例配置:

services:
  user-service:
    # eureka中的服务名
    id: user-service
    # 以/user开头的请求, 会被转发到user-service服务中
    prefix: /user
    # 转发时是否去掉请求前缀, 即/user
    strip-prefix: true
    # 灰度配置
    canary:
      -
        # 对应eurekai注册信息中元数据(metadata map)中key=version的值
        meta: "1.0"
        # 流量比重
        weight: 3
      -
        meta: "2.0"
        weight: 4
      -
        # 对应没有metadata的服务
        meta: ""
        weight: 1

  trends-service:
    id: trends-service
    prefix: /trends
    strip-prefix: false
    # 设置qps限制, 每秒最多请求数
    qps: 1

  order-service:
    id: order-service
    prefix: /order
    strip-prefix: false

  img-service:
    # 如果有host, 则不查注册中心直接使用此地址, 多个地址逗号分隔
    host: localhost:4444,localhost:5555
    prefix: /img
    strip-prefix: false

  log:
    console-only: true
    directory: "logs"
    file-pattern: "logs/gogate.log.%Y-%m-%d"
    file-link: "logs/gogate.log"

自定义过滤器

前置fitler和后置filter都可以在任意位置添加自定义过滤器以实现定制化的功能。

  • 前置过滤器

函数签名为:

type PreFilterFunc func(server *Server, ctx *fasthttp.RequestCtx, newRequest *fasthttp.Request) bool

server: gogate server对象的指针

ctx: 请求上下文对象指针

newRequest: 要转发给下游微服务的请求对象的指针,可以对相关参数进行修改,如header, body, method等

返回true时gogate会继续触发下一个过滤器,返回false则表示请求到此为止, 不会执行后续过滤器,也不会转发请求。

  • 后置过滤器

函数签名名:

type PostFilterFunc func(req *fasthttp.Request, resp *fasthttp.Response) bool

req: 已经转发给微服务的请求对象指针

resp: 微服务返回的响应对象指针, 可进行修改

返回true时gogate会继续触发下一个过滤器,返回false则表示请求到此为止, 不会执行后续过滤器,也不会转发请求。

  • 添加过滤器

Server.AppendPreFilter: 在末尾追加前置过滤器

Server.AppendPostFilter: 在末尾追加后置过滤器

Server.InsertPreFilter: 在指定过滤器的后面插入前置过滤器

Server.InsertPostFilter: 在指定过滤器的后面插入后置过滤器

Server.InsertPreFilterAhead: 插入前置过滤器到最头部

Server.InsertPostFilterAhead: 插入后置过滤器到最头部

Eureka配置

eureka.json文件

gogate配置

gogate.yml文件:

version: 1.0

server:
  # 向eureka注册自己时使用的服务名
  appName: gogate
  host: 0.0.0.0
  port: 8080
  # gateway最大连接数
  maxConnection: 1000
  # gateway请求后端服务超时时间, 毫秒
  timeout: 3000

# 如果eureka, consul都没有启动, 则进入静态模式, 不访问注册中心
eureka:
  enable: false
  # eureka配置文件名
  configFile: eureka.json
  # 路由配置文件名
  routeFile: route.yml
  # eureka剔除服务的最大时间限值, 秒
  evictionDuration: 30
  # 心跳间隔, 秒
  heartbeatInterval: 20

consul:
  enable: true
  # agent地址
  address: 127.0.0.1:8500


traffic:
  # 是否开启流量记录功能
  enableTrafficRecord: true
  # 流量日志文件所在目录
  trafficLogDir: /tmp

redis:
  # 是否使用redis做限速器
  enabled: false
  # 目前只支持单实例, 不支持cluster
  addr: 127.0.0.1:6379
  # 限速器lua代码文件
  rateLimiterLua: lua/rate_limiter.lua

限流器

gogate有两个限流器实现, MemoryRateLimiterRedisRateLimiter,通过gogate.yml配置文件里的redis.enabled控制。前者使用令牌桶算法实现,适用于单实例部署的场景;后者基于 Redis + Lua 实现,适用于多实例部署。但有一个限制是目前Redis只支持连接单个实例,不支持cluster。

流量日志

gogate会记录过去1s内各个微服务的请求数据,包括成功请求数和失败请求数,然后写入/tmp/{service-id}_yyyyMMdd.log文件中:

1527580599228,2,1,user-service
1527580600230,4,1,user-service
1527580601228,1,1,user-service

毫秒时间戳,成功请求数,失败请求数,服务名

如果在过去的1s内没有请求, 则不会向日志中写入任何数据。

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].