以服务于中国广大创业者为己任,立志于做最好的创业网站。

标签云创业博客联系我们

导航菜单

go开发框架,golang微服务架构

  

  杜博戈的前世   

  

     

  

  杜波-Go是目前杜博多语种生态中最热门的项目。《dubbo-go》的最早版本应该可以追溯到2016年,而《dubbo-go》的作者是来自社区的学生鱼雨。   

  

  第一版。当时很多东西都没有现成的轮子,比如Go语言没有netty这样基于事件的网络处理引擎,hessian2协议没有Go。   

  

  语言实现,当时Dubbo没有再开始维护。所以,从协议库到网络引擎,再到上层的dubbo-go,其实都是从头开始写的。   

  

  2018年,携程开始做一些Go语言的中间件,构建内部的Go语言生态,这就需要一个可以匹配携程现有dubbo soa的Go服务框架。   

  

  生态互通。所以我负责重构Dubbo-Go并开源这个版本。当时研究了很多开源的Go语言服务框架,能够支持当时的hessian2协议。   

  

  而所能打通的,只有当时余所写的早期版本。因为携程对社区版的Dubbo做了很多扩展,我们Go是因为需要扩展性。   

  

  语言版本需要一个更容易扩展的版本,而这个版本本身的功能在当时是比较简单的,所以我们找了作者合作,重新构建了一个更好的版本。半年后,在上图第三阶段19   

  

  2006年6月,对dubbo-go进行了基本重构,大致思路为dubbo借鉴。   

  

  的整体代码架构,用Go语言完全改写了一个完整的服务器端和消费者端的Golang rpc/微服务框架。   

  

  后来,我们把重构版dubbo-go 1.0贡献给了Apache。   

  

  基础,到现在已经两个多月了,最近社区发布了1.1版本。到目前为止,包括携程在内的一些公司已经开始在生产环境中试用和推广。   

  

  开始dubbo-go   

  

  现在dubbo-go已经能够很好地与Java版本集成和互操作,而且dubbo-Go本身也是一个完整的Go语言rpc/   

  

  微服务框架,不用java dubbo也可以独立使用。   

  

  这里简单介绍一下用法,写一个hello world的例子。   

  

     

  

  上图显示了一个注册为Dubbo服务的简单java服务,这是一个获取用户信息的简单例子。   

  

     

  

  上图是dubbo-go的客户端,它订阅并调用这个Java Dubbo服务。Go语言客户端需要显式调用SetConsumerService。   

  

  来注册需要订阅的服务,然后通过调用dubbo-Go-hessian2库的registerPOJO方法注册用户对象,做Java和Go。   

  

  语言之间的自定义pojo类型转换。的具体服务调用方法是声明一个GetUser闭包,可以直接调用。   

  

     

  

  上图,类似的,我们可以发布一个基于dubbo-go的GetUser服务器,使用方式类似,发布后可以被dubbo java的客户端调用。   

  

     

  

  如上图所示,我们已经达到了这样一个程度:相同的dubbo-go客户端代码可以调用dubbo-go或Dubbo Java的服务器。   

  

  的服务器;同样的dubbo-go服务器代码可以被Dubbo-go客户端和Java客户端调用,所以Dubbo基本上是作为PPC使用的。   

  

  Go语言的应用和框架的Java应用之间没有障碍,是一个完整的跨语言RPC调用。更重要的是,dubbo-go继承了dubbo。   

  

  的很多优点,比如容易扩展和强大的服务治理功能,如果你在用Go语言开发应用的过程中遇到与Dubbo Java类似的需求。   

  

  打通需求,或者需要找到一个具有完整服务治理功能的Go微服务框架。   

,可以看下我们 dubbo-go 项目。

  

dubbo-go 的组成项目

  

下面介绍一下 dubbo-go 的组成项目,为了方便可以被其他项目直接复用, dubbo-go 拆分成了多个项目,并全部以 Apache 协议开源。

  

apache/dubbo-go

  

dubbo-go 主项目, Dubbo 服务端、客户端完整 Go 语言实现。

  

apache/dubbo-go-hession2

  

目前应用最广泛,与 Java 版本兼容程度最高的 hessian2 协议 Go 语言实现,已经被多个 GolangRPC & Service Mesh

  

项目使用。

  

dubbo-go/getty

  

dubbo-go 异步网络 I/O 库,将网络处理层解耦。

  

dubbo-go/gost

  

基本类库,定义了 timeWheel、hashSet、taskPool 等。

  

dubbo-go/dubbo-go-benchmark

  

用于对 dubbo-go 进行简单的压力测试,性能测试。

  

apache/dubbo-go-hessian2

  

  

先简单介绍一下 dubbo-go-hessian2 项目。该项目就是 hessian2 协议的 Go 语言实现,最基本的可以将 Java

  

的基本数据类型和复杂数据类型(如一些包装类和list接口实现类)与 golang 这边对应。

  

详情可以参考这里。

  

另外 Dubbo Java 服务端可以不捕获异常,将异常类通过 hession2

  

协议序列化通过网络传输给消费端,消费端进行反序列化对该异常对象并进行捕获。我们经过一段时间的整理,目前已经支持在 Go 消费端定义对应 Java 的超过

  

40 种 exception 类,来实现对 Java 异常的捕获,即使用 dubbo-go 也可以做到直接捕获 Java 服务端抛出的异常。

  

另外对于 Java 端 BigDecimal 高精度计算类的支持。涉及到一些金融相关的计算会有类似的需求,所以也对这个类进行了支持。

  

其他的,还有映射 java 端的方法别名,主要的原因是 Go 这边语言的规约,需要被序列化的方法名必须是首字母大写。而 Java

  

这边没有这种规范,所以我们加了一个 hessian 标签的支持,可以允许用户手动映射 Java 端的方法名称。

  

基本上现在的 dubbo-go 已经满足绝大多数与 Java 的类型互通需求,我们近期也在实现对 Java 泛型的支持。

  

dubbo-go/getty

  

  

Go 语言天生就是一个异步网络 I/O 模型,在 linux 上 Go 语言写的网络服务器也是采用的 epoll 作为最底层的数据收发驱动,这跟 java

  

在 linux 的 nio 实现是一样的。所以 Go 语言的网络处理天生就是异步的。我们需要封装的其实是基于 Go

  

的异步网络读写以及之后的处理中间层。getty 将网络数据处理分为三层,入向方向分别经过对网络 i/o 封装的 streaming

  

层、根据不同协议对数据进行序列化反序列化的 codec 层,以及最后数据上升到需要上层消费的 handler 层。出向方向基本与入向经过的相反。每个链接的

  

IO 协程是成对出现的,比如读协程负责读取、 codec 逻辑然后数据到 listener 层,然后最后的事件由业务协程池来处理。

  

该项目目前是与 dubbo-go 解耦出来的,所以大家如果有类似需求可以直接拿来用,目前已经有对于 tcp/udp/websocket 的支持。

  

Apache / dubbo-go

  

  

dubbo-go 主项目,我们重构的这一版主要是基于 Dubbo 的分层代码设计,上图是 dubbo-go 的代码分层。基本上与 Java 版本 Dubbo

  

现有的分层一致,所以 dubbo-go 也继承了 Dubbo 的一些优良特性,比如整洁的代码架构、易于扩展、完善的服务治理功能。

  

我们携程这边,使用的是自己的注册中心,可以在 dubbo-go 扩展机制的基础上灵活扩展而无需去改动 dubbo-go 的源代码。

  

dubbo-go 的功能介绍

  

dubbo-go 已实现功能

  

目前 dubbo-go 已经实现了 Dubbo

  

的常用功能(如负责均衡、集群策略、服务多版本多实现、服务多注册中心多协议发布、泛化调用、服务降级熔断等),其中服务注册发现已经支持

  

zookeeper/etcd/consul/nacos 主流注册中心。这里不展开详细介绍,目前 dubbo-go 支持的功能可以查看项目 readme 中的

  

feature list ,详情参考:https://github.com/apache/dubbo-go#feature-list

  

目前社区正在开发中的功能,主要是早期用户使用过程中提出的一些需求,也是生产落地一些必需的需求,如监控、调用链跟踪以及服务路由、动态配置中心等更高级的服务治理需求。

  

dubbo-go 功能介绍之泛化调用

  

  

这里详细做几个重点功能的介绍。首先是泛化调用,如上图,这个也是社区同学提的需求。该同学公司内部有很多 Dubbo 服务,他们用 Go 做了一个 api

  

gateway 网关,想要把 Dubbo 服务暴露成外网 http 接口。因为内部的 Dubbo 服务比较多,不可能每一个 Dubbo

  

服务都去做一个消费端接口去做适配,这样的话一旦服务端改动,客户端也要改。所以他这边的思路是做基于 dubbo-go 做泛化调用, api-gateway

  

解析出外网请求的地址,解析出想要调用的 Dubbo 服务的目标。基于dubbo-go consumer 泛化调用指定 service、method

  

,以及调用参数。

  

具体的原理是, dubbo-go 这边作为消费端,实际会通过本地 genericService.invoke 方法做代理,参数里面包含了 service

  

name,method name ,还包含被调用目标 service 需要的参数类型、值等数据,这些数据后面会通过 dubbo-go-hession2

  

做转换,会将内容转化成 map 类型,经过网络发送到对应的 Java 服务端,然后 Java 那边是接收的 map 类型的参数,会自动反序列化成自己的

  

pojo 类型。这样就实现了 dubbo-go 作为客户端,泛化调用 Dubbo 服务端的目的。

  

dubbo-go 功能介绍之降级熔断

  

  

降级熔断这边是基于的是大家比较熟悉的 hystrix 的 Go 语言版本,基于 hystrix

  

,用户可以定义熔断规则和降级触发的代码段。降级熔断支持是作为一个独立的 dubbo-go filter

  

,可以灵活选择是否启用,如果不启用就可以在打包的时候不将依赖引入。Filter 层是 dubbo-go

  

中对于请求链路的一个责任链模式抽象,目前有许多功能都是基于动态扩展 filter 链来实现的,包括 trace、leastactive load

  

balacne、log 等。降级熔断设计成一个服务调用端独立的filter可以灵活满足调用端视角对于微服务架构中“防雪崩“的服务治理需求。

  

dubbo-go 功能介绍之动态配置

  

关于动态配置中心, Dubbo 的 2.6 到 2.7 版本做了一个比较大的变化,从之前的 url 配置形式过渡到了支持配置中心 yaml

  

格式配置的形式,治理粒度也从单服务级别的配置支持到了应用级别的配置,不过在2.7版本中还是兼容 2.6 版本 url 形式进行服务配置的。dubbo-go

  

这边考虑到跟 Dubbo2.6 和 2.7 的互通性,同样支持 url 和配置文件方式的服务配置,同时兼容应用级别和服务级别的配置,跟 dubbo

  

保持一致,目前已经实现了zookeeper和apollo作为配置中心的支持。

  

dubbo-go roadmap 2019-2020

  

  

最后是大家比较关注的,社区关于 dubbo-go 2019 年下半年的计划,目前来看主要还是现有功能的补齐和一些问题的修复,我们的目标就是首先做到 Java

  

和 Go 在运行时的兼容互通和功能的一致,其次是查漏补缺 dubbo-go 作为一个完整 Go 语言微服务框架在功能上的可以改进之处。

  

另外值得关注的一点是,预计今年年底, dubbo-go 会发布一个支持 kubernetes

  

作为注册中心的扩展,积极拥抱云原生生态。关于云原生的支持,社区前期做了积极的工作,包括讨论关于 dubbo-go 与 Service Mesh

  

的关系以及在其中的定位,可以肯定的是, dubbo-go 将会配合 Dubbo 社区在 Service Mesh

  

方向的规划并扮演重要角色,我们初步预计会在明年给出与 Service Mesh开源社区项目集成的方案,请大家期待。

  

dubbo-go 社区目前属于快速健康成长状态,从捐赠给 Apache

  

后的不到3个月的时间里,吸引了大批量的活跃开发者和感兴趣的用户,欢迎各位同道在使用或者学习中遇到问题能够来社区讨论或者给予指正,也欢迎对 dubbo-go

  

有潜在需求或者对 dubbo-go 感兴趣的同道能加入到社区中。

  

作者信息: 何鑫铭,目前就职于携程,基础中台研发部技术专家,dubbo-go 共同发起人、主要作者,Apache Dubbo

  

committer,关注互联网中台以及中间件领域。

  

本文为云栖社区内容,未经允许不得转载。