本文介绍: gomicro一个简化分布式开发的微服务生态系统。它为开发分布式应用程序提供了基本构建模块gomiro设计哲学是:通过提供组件工具,明确微服务开发边界,让我们专注于开发业务本身。相比于GoFrame、Gin这类Web框架我们发现微服务框架组件构成更为复杂。Go Micro我们用于编写微服务的RPC框架入门阶段重点理解Go Micro组件即可,其他的组件会在后续文章详细介绍。以上这些就是gomicro RPC框架底层支持组件

Go原生开发有着天然的优势,云原生系统需要扩展耦合弹性管理。Go微服务框架很多,包括:gomicrogozerogokitgo-kratostars-go、dubbo-go、jupiter等等…

Go 的设计就是为云原生时代构建的语言简单高效、快速编译支持现代网络多核计算支持并发内存安全,帮助用户专注于解决问题而不是受限于语言复杂性。

打好基础

要想一文入门Go微服务还是需要有些前提条件的,打好基础:

  1. 已经掌握了Golang基础知识,如果基础薄弱,欢迎学习的我的Go语言学习专栏,查漏补缺。

  2. 了解Protobuf,知晓相关知识点
    补课可以阅读篇文章# 一文带你玩转ProtoBuf

  3. 了解RPC的概念,知晓gRPC如何使用可以阅读这2篇文章快速入门# Go RPC入门指南:RPC的使用边界在哪里?如何实现跨语言调用?# 开发gRPC总共分三步

微服务框架对比

简单整理了一下,让大家有个整体的认识:

简单横评各个框架

框架 作者 开源时间 一句话概述 优势 缺点 最新star
go-micro 国外大佬Asim团队 2015年 是最早,最经典的Go微服务框架之一 轻量级框架,入门简单文档清晰 版本兼容性差,社区活跃度一般 19.4k
go-zero 国内大佬万俊峰团队 2020 提供了微服务框架需要具备的通用能力 社区生态非常好,无论是文档更新还是技术群都很活跃 相比于go-micro比较重,同时也只带一部分的强约束学习门槛比go-micro略高 20.8k
go-kit 国外大佬 2015 Go-kit自己描述为微服务的标准库。像Go一样,go-kit为您提供可用于构建应用程序的单独包。 极度轻量级框架 社区建设一般
tars-go 腾讯开源 2018 tarsgo是tars这个大的C++重量级微服务框架下的go语言服务框架 优势在于很多能力不用从头开始做起,直接依托母体tars 缺点是独立性较差,要选用这个tarsgo的前提,就是要先选用tars这个C++的框架 3.1k
dubbo-go 阿里开源 2019 dubbogo是dubbo这个Java重量级微服务框架下的go语言服务框架 腾讯开源项目类似 腾讯开源项目类似 4.2k
go-kratos B站开源 2019 轻量级的微服务框架,框架定位解决微服务的核心诉求。 暂无,后续补充 暂无,后续补充 19k
jupiter 斗鱼开源 2020 面向服务治理的Golang微服务框架 暂无,后续补充 暂无,后续补充 3.9K

计划系统的介绍2个微服务框架的入门和实战教程“go-micro”和“go-zero”

之所以选择两个框架是因为:

  1. 我司使用的go-micro,发现这个框架开发微服务够经典,够纯粹,非常适合入门学习微服务。

  2. 通过和有经验的小伙伴交流,go-zero也是一个非常优秀的框架,在国内社区生态建设和维护上,完美适配国内开源的现状,社区非常活跃,使用率会越来越高。

go-zero的入门指南,在后面会为大家分享,欢迎关注我。

微服务

概念

微服务是一种软件架构模式用于将大型整体应用程序分解为更小的可管理独立服务,这些独立服务通过跨语言协议进行通信每个服务都专注于做好一件事情。

软件架构演进史

如果你对上面这段定义表示晦涩难懂,可以阅读这篇文章# 给想转Go或者Go进阶同学的一些建议

结合自己的经历聊了聊软件架构演进史:从单机架构到集中式架构,再到当前主流的分布式微服务架构,介绍了微服务和领域驱动设计DDD的知识点。

简单理解

用我的话解释微服务就是:

复杂项目拆成微(小的)服务,明确服务与服务之间边界,服务内部内聚,服务之间耦合

微服务的好处

  1. 降低开发难度:微服务架构使得团队各个成员需要关注自己业务管理自己的服务;
  2. 独立部署各个微服务之间可以分开部署,不影响其他服务的使用,上线部署需要其他团队的配合支持
  3. 提高容错和容灾能力:微服务之间独立最大程度降低一个服务对另外一个服务的影响;
  4. 提高团队执行效率各个团队独立开发部署、维护项目,不需要等待其他团队支持
  5. 提高项目复用:微服务的架构设计,能将高复用利用到极致,不同的服务不会做同一件事情,避免资源浪费
  6. 降低企业成本:微服务支持语言、跨团队开发,不需要大规模的替换单体架构或者集中式架构中的工程师

我们在了解微服务的好处之后,继续探究一下go-micro的特点,了解一下go-micro是如何实现微服务开发的:

go-micro概述

go-micro是一个简化分布式开发的微服务生态系统。它为开发分布式应用程序提供了基本的构建模块

go-miro的设计哲学是:通过提供组件工具,明确微服务开发的边界,让我们专注于开发业务本身。

下面就重点介绍一下构成组件

构成组件

Go Micro

API

Sidecar

Web

CLI

Bot

总结

相比于GoFrame、Gin这类Web框架,我们发现微服务框架的组件构成更为复杂

Go Micro是我们用于编写微服务的RPC框架,入门阶段重点理解Go Micro组件即可,其他的组件会在后续文章详细介绍。

下面我们重点看一下Go Micro组件的架构:

Go Micro组件架构

Go Micro为微服务提供了基本的构建模块,其目标简化分布式系统开发。

因为微服务是一种架构模式,Micro的架构思路是通过工具组件进行拆分,简化我们开发微服务项目的难度;Micro的设计哲学是可插拔的插件化架构。

Go-micro是微服务的独立RPC框架,也是我们学习go-micro的核心

我们看下面的架构图

架构图中最底层的组件对于初学微服务的同学肯定不熟悉,下面来重点介绍一下:

Registry注册中心

注册中心提供可插入的服务发现库,来查找正在运行的服务。 默认实现方式consul

我们也可以很方便的修改etcdkubernetes等。毕竟可插拔是go-micro重要特性

Selector负载均衡

Selector选择器实现go-micro的负载均衡机制。

原理是这样的:客户端服务器发出请求时,首先查询服务的注册中心,注册中心会返回一个正在运行服务的节点列表选择器将选择这些节点中的其中一个用于查询请求。

多次调用选择器将使用平衡算法。目前的方法循环法、随机哈希黑名单。go-micro就是通过这种机制实现负载均衡的。

Broker事件驱动发布订阅

Broker是发布和订阅的可插入接口

微服务是一个事件驱动的架构,发布和订阅事件应该是一流的公民。目前的实现包括nats,rabbitmqhttp

Transport消息传输

传输是通过点对点传输消息的可插拔接口

目前的实现httprabbitmqnats。通过提供这种抽象运输可以无缝地换出。

总结

以上这些就是go-micro RPC框架的底层支持组件。

我们了解微服务和go-micro的知识点后可能还是有些懵,这很正常,毕竟知识点过于密集。

快速入门

下面和我一起动手实践吧:

注意:go-micro版本兼容问题最被大家吐槽,下面我演示依赖安装示例代码,均以我司使用的go-micro v2版本

我决定使用# 和大象装冰箱一样:开发gRPC总共分三步示例,编写go-micro的入门示例
通过原生开发gRPC和使用go-micro开发做个对比,你会发现使用go-micro开发微服务多么的简单

我们参考go-micro的官方示例,实现一个问候服务,实现经典的Hello World

准备工作

1. 安装micro v2

#安装go-micro
go get github.com/micro/go-micro/v2
#安装工具集
go get github.com/micro/micro/v2

2. 安装protobuf插件

#安装protobuf
go get github.com/golang/protobuf/{proto,protoc-gen-go}
#指定版本安装生成micro代码工具集
go get github.com/micro/micro/v2/cmd/protoc-gen-micro

我们在编写proto文件之后,使用protoc-gen-go自动生成代码,所以需要提前安装依赖

3. 创建项目结构

我们在合适的目录创建项目目录比如选择在我的Go安装目录/Users/wangzhongyang/go/src/
新建go-micro目录,用于统一管理go-micro相关的项目。

cd /Users/wangzhongyang/go/src/
mkdir go-micro

在go-micro目录创建helloworld目录,用于编写本次的演示项目。

cd go-micro
mkdir helloworld
cd helloworld

helloworld目录下新建proto目录用于编写proto文件,另外创建main.go文件作为服务的入口文件

touch main.go
mkdir proto

准备工作做好之后,下面开发微服务的步骤和“开发gRPC总共分三步”是一样的:

  1. proto文件定义服务和消息
  2. 使用protoc工具生成代码
  3. 编写业务逻辑代码提供服务

1. 编写proto文件

我们在helloword/proto目录下 新建greeter.proto文件

编写proto文件和用什么微服务框架没有关系,我们都需要定义syntaxservicemessage

syntax = "proto3";

//pbprotoc 生成go文件的包名
option go_package ="./;pb";

service Greeter {
  rpc Hello(Request) returns (Response) {}
}

message Request {
  string name = 1;
}

message Response {
  string greeting = 1;
}

2. 使用protoc工具生成代码

我们打开控制台切换proto目录下,比如我的目录是:

cd  /Users/wangzhongyang/go/src/go-micro/helloworld/proto

执行自动生成代码命令:

注意:我们必须使用带有 micro pluginprotoc 编译它。

protoc --proto_path=. --micro_out=. --go_out=. greeter.proto

我们发现执行上述命令后,生成pb.go文件和pb.micro.go文件。

但是有报错,不用担心,接着往下看:

2.1 解决报错

报错原因是因为没有导入依赖,我们在项目根目录执行

go mod init
go mod tidy

同步依赖后,发现报错消失了:

3. 编写业务逻辑代码提供服务

3.1 编写服务端

  1. 我们直接main.go中编写服务
  2. import中的 proto 对应的目录改成自己的。你自己module名称可以在go.mod查看

  1. 关键代码已加注释,逻辑和# 开发gRPC总共分三步 的入门实践部分非常像。
package main

import (
   "context"
   "fmt"
   micro "github.com/micro/go-micro/v2"
   proto "go-micro/helloworld/proto" //注意这里修改成你自己
)

//定义结构体 作为方法调用
type Greeter struct{}

//实现 .pb.micro.go中的Hello方法 定义rsp的返回值
func (g *Greeter) Hello(ctx context.Context, req *proto.Request, rsp *proto.Response) error {
   rsp.Greeting = "Hello " + req.Name
   return nil
}

func main() {
   //定义服务
   service := micro.NewService(
      micro.Name("greeter"),
   )
   
   //服务初始化
   service.Init()

   // 注册handler
   err := proto.RegisterGreeterHandler(service.Server(), new(Greeter))
   if err != nil {
      return
   }

   //启动服务
   if err := service.Run(); err != nil {
      fmt.Println(err)
   }
}

服务端编写好之后我们再编写客户端

3.2 编写客户端

在项目根目录下,新建client目录,新建client.go文件,用于编写客户端代码

创建目录和文件:

mkdir client
cd client
touch client.go

编写代码:

  1. 关键逻辑已经添加注释
  2. NewGreeterService()和Hello()都是proto文件自动生成的的,定义在.pb.micro文件中
package main

import (
   "context"
   "fmt"
   micro "github.com/micro/go-micro/v2"
   proto "go-micro/helloworld/proto"
)

func main() {
   //创建一个新的服务 命名
   service := micro.NewService(micro.Name("greeter.client"))
   //服务初始化
   service.Init()

   //创建服务 绑定客户这个方法是在proto生成的文件中定义
   greeter := proto.NewGreeterService("greeter", service.Client())

   //调用Hello方法 Hello方法同样是在proto生成的文件中定义
   rsp, err := greeter.Hello(context.TODO(), &proto.Request{Name: "World"})
   if err != nil {
      fmt.Println(err)
   }

   //打印结果
   fmt.Println(rsp.Greeting)
}

我们来看一下 .pb.micro.go文件的源码
重点看一下Hello方法:

这里我们就编码完毕,看下执行效果

3.3 启动服务,进行调用

1.先启动服务端

我们打开控制台切换到项目根目录下,执行命令

go run main.go

执行效果如下,服务端已经启动:

2.再启动客户端

我们另外打开一个控制台,启动客户端服务:

cd go-micro/helloworld/client/

go run client.go

执行效果如下,和我们预期的效果一样,成功的打印出了Hello World

总结

分布式微服务架构已成趋势,越来越多的公司在从单体应用或集中式应用分布式应用转型。开篇类比了主流Go微服务框架的特点,Go的微服务生态可以说是百家争鸣。

本文也介绍了微服务的特点和优势,go-micro的架构和构成组件;类比原生开发rpc项目,用go-micro实现了经典的Hello World问候服务,带大家入门了微服务开发。

关于专栏

近期会更新系列Go实战进阶的文章,欢迎大家关注我的:
# Go语言进阶实战专栏

这是近期会更新文章的知识脉络图,感兴趣的小伙伴可以关注一波,欢迎日常催更。

问题建议欢迎留言讨论

一起学习

欢迎在CSDN私信我,也欢迎 加我好友 一起学习

原文地址:https://blog.csdn.net/w425772719/article/details/128802790

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_34978.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注