Go chassis是一个go语言微服务开发框架
java
经过这篇文章中,我将从设计思路到源码剖析来深度分析Go Chassis。而且介绍本身在实践过程当中的go语言性能调优和最佳实践,最后将使用go chassis编写一个http服务,此为上篇,将主要介绍go chassis的运行机制mysql
项目地址:github.com/go-chassis/…git
go依然是一门新兴的语言,和java比它还很是年轻,不过随着kubenetes和docker等项目的成功,能够说go语言已经成为了很是好的中间层开发语言,而且逐渐流行起来。github
编译速度快,支持多平台,内存占用低,轻量级协程等。算法
他的协程设计下降了开发者门槛,让更多人能够轻松地编写支持高并发的后台服务sql
当你要解决微服务模式带来的新问题的时候你要实现多少代码来处理分布式带来的复杂度?docker
我相信一个成熟的开发框架须要2万行以上的代码。而go chassis正是这样一个框架编程
- go chassis集成了不少的功能,提供了一站式服务,可以让用户在一个方案中,得到路由管理,注册发现,负载均衡,限流,指标监控,分布式追踪等大量功能。缓存
- go chassis是一个协议中立的开发框架,它不只支持http,也支持rpc协议,甚至能够集成mysql等中间件的协议。并将它们归入统一的治理。bash
- go chasis支持Istio控制面板,也就是说你能够将它与envoy进行混合使用,但只须要使用istio便可,它支持原生的istio配置管理。以此使服务吞吐提高,CPU占用下降。
- go chassis是插件化设计,支持用户开发定制模块,并接入到框架中
主要有如下几点:
● 插件化注册中心: 默认支持Service Center,kubernetes,istio
● 动态治理框架: 经过此框架,开发者可实现进程运行时配置热加载
● 插件化协议: 开发者可实现本身的RPC协议,默认实现了 http 和highway(RPC)
● 熔断降级: 支持根据超时,并发,错误率等进行服务的熔断
● 容错:支持重试次数等配置,并支持backoff退让重试,
● 路由管理: 可根据流量权重和Header匹配等配置规则,轻松实现金丝雀发布
● 客户端负载均衡: 支持定制策略
● 限流: 支持客户端和服务端限流
● 插件化Cipher: 支持开发者自定义加解密工具,并应用于AKSK和TLS 证书
● 处理链: 可支持在通讯的过程当中加入定制的业务逻辑
● Metrics: 支持自动导出Prometheus格式的运行时监控数据
● Tracing: 使用opentracing,支持用户快速对接不一样分布式追踪系统
● Logger: 日志工具支持扩展并下沉到不一样存储中
● 治理: 可经过动态治理框架,在运行时热加载,熔断,负载均衡,路由等配置信息
● 最大的灵活性和扩展性
协议是容许开发者灵活扩展的,在通讯管道中任意的插入本身的特殊业务逻辑。
● 易用性
开发者能够用最小化的配置和代码来启动框架,而且框架内部提供友好的API供用户使用,每一个模块甚至能够拆开使用,功能任意剪裁。
● 服务可治理
提供客户端负载均衡,熔断降级,容错,限流,路由管理等功能使分布式系统可治理,同时提供错误注入功能,来提早模拟分布式系统中的错误,以使本身的系统更增强壮。
● 服务可视化
微服务运行时产生的监控数据可以导出到监控系统,使数据可视化。
● 运行时配置热加载
分布式环境中,存在大量进程,若是由于更改配置就要发布新的软件包,会有必定成本,若是登录到机器上去改配置再重启,更是费时费力。go chassis提供动态配置框架来帮开发者解决配置热加载问题。这也是服务动态治理的基础。
以下图所示:
● 架构思路
● 编程接口:拥有RPC和Rest 2种编程模型
● 运行模型:使用Handler Chain与Invocation概念统一了不一样协议
● 传输层:一个进程拥有多种协议。同协议可运行多个协议服务实例,运行在不一样端口,使用端口进行API隔离
● Handler chain可任意插入业务逻辑
● Http服务可支持自动挂载 Promethues数据到指定的API路径。
● 日志可支持扩展,好比输出到kafka等服务中
● 请求处理过程
不一样协议请求进入到对应的Server,Server将具体的协议请求转换为Invocation统一抽象模型,并传入Handler chain,在这里Chassis已经默认实现了不少的Handler,好比熔断,限流,路由管理,客户端负载均衡,Metrics收集,分布式追踪,错误注入等,因为handler根据统一模型Invocation进行处理,没必要每一个协议开发出来都本身开发一套治理。处理链可经过配置任意剪裁。最终再进入Transport handler,使用目标微服务的协议客户端传输到目标。
这里提到的几个关键对象在后面会详细介绍。
● 处理链与Invocation
这个概念是从Java chassis引入的, 框架的编程接口层、运行模型层和传输层就是经过这个对象进行解耦,它是多协议支持的基础。能够参考它的代码:
Invocation为一个结构体,它将各个协议的内容抽象了,运行不一样协议的request都可以统一对应到一次Invocation中,好比request的Payload,以及框架的治理相关信息。
● Handler
Handler是微服务在运行过程当中在框架层面里的一个最小处理单元。go chassis经过handler和handler的组装实现组件化的运行模型架构。其基本的使用方式就是实现接口、注册逻辑:
2. 开发者实现该接口后可经过API注册进框架
● Handler Chain
用于加载一系列Handler并处理消息,目前支持负载均衡,路由管理,监控等功能,用户能够经过配置文件定义加载多种handler。请求调用时,会按照配置文件中的定义的顺序进入handler进行处理
Handler的设计能够保证每个handler都能获得后面的handler的执行结果。好比:熔断和网络穿的功能就在chain当中,每当传输失败,都会被熔断拿到错误结果,并计算,当达到必定阈值,便会出发熔断。
● Invoker
因为RPC和Http的编程风格不一样,go chassis使用2种不一样的Invoker来解决调用,不管哪一种Invoker都会初始化一个Invocation并最终进入处理链中进行处理,最终进入各协议的Client实现并传输到目标服务中,这一切对用户都是透明的。
RPC
为了下降用户学习成本,使用了go语言标准库中net/rpc的调用风格
Http
为了下降用户学习成本,支持了go语言通用的http调用方式,容许用户任意操控原生http request 与 response,而且没有任何限制
接下来,用一个微服务调用过程当中最基本的Consumer到Provider的业务请求流程来看一下前面的那些关键对象是如何协同工做的.
● 客户端发送请求
● 服务端接收请求
go的动态能力相对有限,go 1.8提供了插件能力,可是会给build带来复杂度,咱们先来看看Java怎么解决插件化的
Class<?> act = Class.forName("com.bla.TestActivity");复制代码
基于这个能力也出现了Spring这样的项目,开发者能够轻松地解决插件化的问题
但是go语言该怎么作呢?
下面以Go chassis的实践为例
提供接口与Map定义
开发者须要实现接口,并实现NewFunc返回具体实现
注册插件
经过调用API进行插件安装
使用插件
考虑到易用性贴近Spring的风格,chassis使用yaml格式的配置文件来管理插件。
如下为实现思路
启动和初始化机制以下:
支持的插件
chassis框架支持如下插件,具体请参考gitbook文档https://go-chassis.readthedocs.io/en/latest/。
客户端负载均衡器负责使用本地的注册中心缓存来进行服务发现。
go chassis 封装了不少的高级特性
为了能让用户轻松地制造系统混乱,在Consumer侧,实现了错误注入机制,能够根据配置定义错误或者故意制造调用延迟,来测试分布式系统遇到问题时的容错能力,一样支持运行时动态加载配置。目前只支持简单的错误和延迟以及发生百分比
开发者甚至能够经过此接口为一个协议安装错误注入插件,可彻底替代目前的错误注入实现
go micro架构:
图片来自go micro官网https://micro.mu/docs/images/go-micro.png
这里我引用micro.mu的关于go micro与go kit对比
Go micro是一个插件化RPC分布式开发框架,能够开箱即用,也能够任意定制本身的RPC协议中的每一个模块。他是一个eco system,如今已经有大量的插件实现,并在go-micro基础之上有了不少的新框架,Micro组织下有许多围绕go-micro创建的子项目。
Go kit是一个用来构建微服务的的工具包,每一个包都是独立的,开发者本身选择须要的工具组装本身的微服务,包含了丰富的治理功能,熔断,监控,限流等,且拥有丰富的插件化协议和注册中心。
Go chassis是插件化框架,与Go micro的不一样在于,go chassis提供的能力是插件化协议,你能够将http或RPC,甚至是Mysql,Redis等协议接入到框架中,而且提供一站式功能,将熔断,限流,监控等功能所有集成到框架中,开发者无需本身寻找这些方案。拥有3者中最丰富的治理功能。一样拥有开放的定制能力,可是做为一个新的框架,生态尚需完善。
开发者能够经过开发体验和特性支持对框架进行选型。