写点什么

Go 语言微服务开发框架实践(上篇)

  • 2020-03-30
  • 本文字数:4114 字

    阅读完需:约 13 分钟

Go语言微服务开发框架实践(上篇)

Go chassis 是华为开源的一个 go 语言微服务开发框架。通过这篇文章中,我将从设计思路到源码剖析来深度分析 Go Chassis。并且介绍自己在实践过程中的 go 语言性能调优和最佳实践,最后将使用 go chassis 编写一个 http 服务,此为上篇,将主要介绍 go chassis 的运行机制。

为什么我们要用 go 语言来开发微服务?

go 依然是一门新兴的语言,和 java 比它还非常年轻,不过随着 kubenetes 和 docker 等项目的成功,可以说 go 语言已经成为了非常好的中间层开发语言,并且逐渐流行起来。编译速度快,支持多平台,内存占用低,轻量级协程等。它的协程设计降低了开发者门槛,让更多人可以轻松地编写支持高并发的后台服务

为什么使用 Go chassis

  • go chassis 集成了很多的功能,提供了一站式服务,能够让用户在一个方案中,获得路由管理,注册发现,负载均衡,限流,指标监控,分布式追踪等大量功能。

  • go chassis 是一个协议中立的开发框架,它不仅支持 http,也支持 rpc 协议,甚至可以集成 mysql 等中间件的协议。并将它们纳入统一的治理。

  • go chasis 支持 Istio 控制面板,也就是说你可以将它与 envoy 进行混合使用,但只需要使用 istio 即可,它支持原生的 istio 配置管理。以此使服务吞吐提升,CPU 占用降低。

  • go chassis 是插件化设计,支持用户开发定制模块,并接入到框架中

go chassis 特性

主要有以下几点:


  • 插件化注册中心: 默认支持 Service Center,kubernetes,istio

  • 动态治理框架: 通过此框架,开发者可实现进程运行时配置热加载

  • 插件化协议: 开发者可实现自己的 RPC 协议,默认实现了 http 和 highway(RPC)

  • 熔断降级: 支持根据超时,并发,错误率等进行服务的熔断

  • 容错:支持重试次数等配置,并支持 backoff 退让重试,

  • 路由管理: 可根据流量权重和 Header 匹配等配置规则,轻松实现金丝雀发布

  • 客户端负载均衡: 支持定制策略

  • 限流: 支持客户端和服务端限流

  • 插件化 Cipher: 支持开发者自定义加解密工具,并应用于 AKSK 和 TLS 证书

  • 处理链: 可支持在通信的过程中加入定制的业务逻辑

  • Metrics: 支持自动导出 Prometheus 格式的运行时监控数据

  • Tracing: 使用 opentracing,支持用户快速对接不同分布式追踪系统

  • Logger: 日志工具支持扩展并下沉到不同存储中

  • 治理: 可通过动态治理框架,在运行时热加载,熔断,负载均衡,路由等配置信息

设计目标

  • 最大的灵活性和扩展性

  • 协议是允许开发者灵活扩展的,在通信管道中任意的插入自己的特殊业务逻辑。

  • 易用性

  • 开发者可以用最小化的配置和代码来启动框架,并且框架内部提供友好的 API 供用户使用,每个模块甚至可以拆开使用,功能任意剪裁。

  • 服务可治理

  • 提供客户端负载均衡,熔断降级,容错,限流,路由管理等功能使分布式系统可治理,同时提供错误注入功能,来提前模拟分布式系统中的错误,以使自己的系统更加强壮。

  • 服务可视化

  • 微服务运行时产生的监控数据能够导出到监控系统,使数据可视化。

  • 运行时配置热加载

  • 分布式环境中,存在大量进程,如果因为更改配置就要发布新的软件包,会有一定成本,如果登陆到机器上去改配置再重启,更是费时费力。go chassis 提供动态配置框架来帮开发者解决配置热加载问题。这也是服务动态治理的基础。

架构概述

如下图所示:



架构思路


1.解耦的编程接口、运行模型、传输层


  • 编程接口:拥有 RPC 和 Rest 2 种编程模型

  • 运行模型:使用 Handler Chain 与 Invocation 概念统一了不同协议

  • 传输层:一个进程拥有多种协议。同协议可运行多个协议服务实例,运行在不同端口,使用端口进行 API 隔离


  1. 基于 Handler chain 模式的插件化架构


  • Handler chain 可任意插入业务逻辑


3.基于运行时动态配置的服务治理


4.相同的运行模型和统一的治理能力


5.相同的运维支撑方式


  • Http 服务可支持自动挂载 Promethues 数据到指定的 API 路径。

  • 日志可支持扩展,比如输出到 kafka 等服务中


6.注册中心拆分为 Registrator 和 Service Discovery2 个接口分别负责注册和发现,可以支持平台发现和客户端注册


  • 请求处理过程


不同协议请求进入到对应的 Server,Server 将具体的协议请求转换为 Invocation 统一抽象模型,并传入 Handler chain,在这里 Chassis 已经默认实现了很多的 Handler,比如熔断,限流,路由管理,客户端负载均衡,Metrics 收集,分布式追踪,错误注入等,由于 handler 根据统一模型 Invocation 进行处理,不必每个协议开发出来都自己开发一套治理。处理链可通过配置任意剪裁。最终再进入 Transport handler,使用目标微服务的协议客户端传输到目标。这里提到的几个关键对象在后面会详细介绍。

实现详解

基本概念


  • 处理链与 Invocation


这个概念是从 Java chassis 引入的, 框架的编程接口层、运行模型层和传输层就是通过这个对象进行解耦,它是多协议支持的基础。它将各个协议的内容抽象了,运行不同协议的 request 都能够统一对应到一次 Invocation 中,比如 request 的 Payload,以及框架的治理相关信息。


  • Handler

  • Handler 是微服务在运行过程中在框架层面里的一个最小处理单元。go chassis 通过 handler 和 handler 的组装实现组件化的运行模型架构。其基本的使用方式就是实现接口、注册逻辑:


1.实现基本接口



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 的业务请求流程来看一下前面的那些关键对象是如何协同工作的.


  • 客户端发送请求



开发者使用 Invoker 来发起请求,Invoker 创建统一 Invocation 对象


1.Invocation 进入处理链进行处理,比如熔断,限流等


2.进入 Load Balancing 后,会根据 Strategy 和目标协议选择一个 IP:port


3.将协议和 IP:port 继续传送到 Transport 后,根据协议选择具体的 Client 实现,并传入 IP port 进行发送


  • 服务端接收请求


1.接收到协议请求后,由各协议 Server 转为统一的 Invocation 模型


2.Invocation 进入处理链处理,比如限流,分布式追踪


3.处理结束后,进入具体的业务处理逻辑

插件化机制

go 的动态能力相对有限,go 1.8 提供了插件能力,但是会给 build 带来复杂度,我们先来看看 Java 怎么解决插件化的:


Class<?> act = Class.forName("com.bla.TestActivity");
复制代码


基于这个能力也出现了 Spring 这样的项目,开发者可以轻松地解决插件化的问题


可是 go 语言该怎么做呢?


下面以 Go chassis 的实践为例

提供接口与 Map 定义


开发者需要实现接口,并实现 NewFunc 返回具体实现

注册插件

通过调用 API 进行插件安装


使用插件

考虑到易用性贴近 Spring 的风格,chassis 使用 yaml 格式的配置文件来管理插件。


以下为实现思路


启动和初始化机制如下:



1.通过文件指定加载的插件,在 Server 之上我们封装 Server manager 管理所有协议的 Server,并负责注册到注册中心,,收到系统终止信号时,负责反注册


2.使用了 Client manager 与


https://github.com/ServiceComb/gochassis/blob/master/core/handler/transport_handler.go


对 client 进行封装,按协议,微服务,实例的唯独进行 client 初始化,即每个实例都有专属 client。

支持的插件

chassis 框架支持以下插件,具体请参考 gitbook文档


1.Handler


2.Provider


3.Cipher


4.Bootstrap


5.Logger


6.Config Source


7.Registry


8.InjectFault


9.Server


10.Client


11.Strategy


12.Tracing

客户端负载均衡

客户端负载均衡器负责使用本地的注册中心缓存来进行服务发现。


go chassis 封装了很多的高级特性


1.融合了 Backoff 算法,以使网络流量稳定。


2.容错支持在请求错误后以怎样的策略进行重试


3.会话粘滞与延迟感知 Strategy 实现


4.动态治理,支持运行时热加载以上配置


5.支持目标服务级别的细粒度负载均衡策略配置(即一进程针对访问不同微服务,可控制负载均衡策略)

错误注入

为了能让用户轻松地制造系统混乱,在 Consumer 侧,实现了错误注入机制,可以根据配置定义错误或者故意制造调用延迟,来测试分布式系统遇到问题时的容错能力,同样支持运行时动态加载配置。目前只支持简单的错误和延迟以及发生百分比



开发者甚至可以通过此接口为一个协议安装错误注入插件,可完全替代目前的错误注入实现

与其他微服务开发框架的对比

go micro 架构:



图片来自 go micro官网


这里我引用 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 者中最丰富的治理功能。同样拥有开放的定制能力,但是作为一个新的框架,生态尚需完善。


开发者可以通过开发体验和特性支持对框架进行选型。


本文转载自 华为云产品与解决方案 公众号。


原文链接:https://mp.weixin.qq.com/s/nA9sNf2RfpHnwrIDOaQsyA


2020-03-30 14:063967

评论

发布
暂无评论
发现更多内容

天翼云联手平凯星辰共建开源分布式数据库实验室

天翼云开发者社区

千字带你了解什么是 RPC 协议

踏雪痕

RPC 3月程序媛福利 3月月更

3天掌握Flask开发项目系列博客之二,操作数据库

梦想橡皮擦

3月月更

智能家居市场白热化,小程序助力生态合作新模式

Speedoooo

小程序生态 智慧小区 小程序容器 智慧家居 智慧物业

如何设计良好的技术项目文档结构

老张

项目管理 交付质量

使用基于 WebRTC 的 JavaScript API 在浏览器环境里调用本机摄像头

汪子熙

JavaScript 前端 WebRTC 摄像头 3月月更

对微博系统中“微博评论”的高性能高可用计算架构的一点思考

晨亮

「架构实战营」

flask POST请求,数据入库,文件上传,一文看懂,3天掌握Flask开发项目系列博客之三

梦想橡皮擦

3月月更

Python 递归函数返回值为 None 的解决办法

AlwaysBeta

Python 递归

作业五

Geek_f3e842

架构实战营

拥抱国产云桌面,焱融科技与酷栈科技完成产品兼容认证

焱融科技

云计算 分布式 云原生 高性能 文件存储

向工程腐化开炮|资源治理

阿里巴巴终端技术

Java android 资源管理

云原生网络利器--Cilium 之 eBPF 篇

Daocloud 道客

云原生 ebpf cilium

阿里云神龙AI加速引擎帮助vivo将训练性能提升30%-70%

阿里云弹性计算

AI gpu 神龙架构 加速引擎

如何捕获和分析 JavaScript Error

喀拉峻

前端

创建 Node.js 视频流应用之后端

devpoint

node.js Video Express 3月月更

如何在 Python 中反转字符串?

Ethereal

融云 IM +RTC 重磅优惠上线!15 天免费体验,1 年服务买一赠一

融云 RongCloud

《人民日报》刊文:天翼云持续创新为数据安全保驾护航

天翼云开发者社区

聊聊 Pulsar:编译 Pulsar 源码并搭建源码环境

老周聊架构

云原生 Apache Pulsar 3月月更

CVE-2022-22947 远程代码执行漏洞复现分析

网络安全学海

黑客 网络安全 信息安全 渗透测试 WEB安全

持续集成容器篇:Docker与自动化打包

Docker 架构 持续集成 jenkins 持续交付

天翼云供应链API安全治理实践获“优秀治理实践奖”

天翼云开发者社区

WMS系统与ERP仓储管理的差异

源字节1号

开源 后端 前端开发 WMS系统 ERP系统

在线MySQL,SQL Server建表语句生成JSON测试数据工具

入门小站

工具

东数西算加快云网与数据融合天翼云架起云间高速

天翼云开发者社区

每秒百万条信息查询天翼云助力江苏核酸检测信息查询

天翼云开发者社区

终端常用快捷键

刁架构

终端 快捷键 iterm2

无影云电脑支持企业快速实现居家办公

阿里云弹性计算

远程办公 数据安全 无影云电脑

确保数据中心物理安全的五种方法

Ethereal

欧拉的奇异之旅·共赴开源时代

白洞计划

Go语言微服务开发框架实践(上篇)_语言 & 开发_华为云产品与解决方案_InfoQ精选文章