-
2020-11-09 20:13:48
在前面使用gRPC一步一步搭建使用流程,但是以上这些具体的方案都是为了解决微服务实践过程中具体的某个问题而提出的,实现微服务架构的项目开发。在具体的项目开发过程中,开发者聚焦的是业务逻辑的开发和功能的实现,大量的环境配置,调试搭建等基础性工作会耗费相当一部分的精力,因此有必要将微服务架构中所涉及到的,相关的解决方案做集中管理和维护。这就是我们要学习的Micro。
Go-Micro
介绍
Micro是一个简化分布式开发的微服务生态系统,该系统为开发分布式应用程序提供了高效,便捷的模块构建。主要目的是简化分布式系统的开发。micro是一个微服务工具包,是由一系列的工具包组成的,而Go-Micro是用在Go中编写微服务的插件式RPC框架。它提供了用于服务发现,客户端负载平衡,编码,同步和异步通信库。
特性
- Registry:主要负责服务注册和发现功能。我们之前学习过的consul,就可以和此处的Registry结合起来,实现服务的发现功能。
- Selector:selector主要的作用是实现服务的负载均衡功能。当某个客户端发起请求时,将首先查询服务注册表,返回当前系统中可用的服务列表,然后从中选择其中一个节点进行查询,保证节点可用。
- Broker:Broker是go-micro框架中事件发布和订阅的接口,主要是用消息队列的方式实现信息的接收和发布,用于处理系统间的异步功能。
- Codec:go-micro中数据传输过程中的编码和解码接口。go-micro中有多重编码方式,默认的实现方式是protobuf,除此之外,还有json等格式。
- Transport:go-micro框架中的通信接口,有很多的实现方案可以选择,默认使用的是http形式的通信方式,除此以外,还有grpc等通信方式。
- Client和Server:分别是go-micro中的客户端接口和服务端接口。client负责调用,server负责等待请求处理。
安装
1.安装consul
consul环境是go-micro默认使用的服务发现方式。具体安装参考链接https://www.cnblogs.com/qingmuchuanqi48/p/13121748.html
2.安装protobuf和依赖
protobuf在前面已经安装过,就不再提及
3.Go-micro安装
go get github.com/micro/go-micro
创建微服务
服务的定义
在micro框架中,服务用接口来进行定义,服务被定义为Service,完整的接口定义如下:
type Service interface { Init(...Option) Options() Options Client() client.Client Server() server.Server Run() error String() string }
在该接口中,定义了一个服务实例具体要包含的方法,分别是:Init、Options、Client、Server、Run、String等6个方法。
初始化服务实例
micro框架,除了提供Service的定义外,提供创建服务实例的方法供开发者调用:
service := micro.NewService()
如上是最简单一种创建service实例的方式。NewService可以接受一个Options类型的可选项参数。NewService的定义如下:
func NewService(opts ...Option) Service { return newService(opts...) }
Options可选项配置
关于Options可配置选项,有很多可以选择的设置项。micro框架包中包含了options.go文件,定义了详细的可选项配置的内容。最基本常见的配置项有:服务名称,服务的版本,服务的地址,服务:
//服务名称 func Name(n string) Option { return func(o *Options) { o.Server.Init(server.Name(n)) } } //服务版本 func Version(v string) Option { return func(o *Options) { o.Server.Init(server.Version(v)) } } //服务部署地址 func Address(addr string) Option { return func(o *Options) { o.Server.Init(server.Address(addr)) } } //元数据项设置 func Metadata(md map[string]string) Option { return func(o *Options) { o.Server.Init(server.Metadata(md)) } }
完整的实例化对象代码如下所示:
func main() { //创建一个新的服务对象实例 service := micro.NewService( micro.Name("helloservice"), micro.Version("v1.0.0"), ) }
开发者可以直接调用micro.Name为服务设置名称,设置版本号等信息。在对应的函数内部,调用了server.Server.Init函数对配置项进行初始化。
定义服务接口,实现服务业务逻辑
在前面的文章中,已经学习掌握了使用protobuf定义服务接口,并对服务进行具体实现。使用protobuf定义服务接口并自动生成go语言文件,需要经过以下几个步骤,我们通过示例进行说明:
我们依然通过案例来讲解相关的知识点:在学校的教务系统中,有学生信息管理的需求。学生信息包含学生姓名,学生班级,学习成绩组成;可以根据学生姓名查询学生的相关信息,我们通过rpc调用和学生服务来实现该案例。
定义.proto文件
使用proto3语法定义数据结构体和服务方法。具体定义内容如下:
syntax = 'proto3'; package message; //学生数据体 message Student { string name = 1; //姓名 string classes = 2; //班级 int32 grade = 3; //分数 } //请求数据体定义 message StudentRequest { string name = 1; } //学生服务 service StudentService { //查询学生信息服务 rpc GetStudent (StudentRequest) returns (Student); }
2、编译.proto文件
在原来学习gRPC框架时,我们是将.proto文件按照grpc插件的标准来进行编译。而现在,我们学习的是go-micro,因此我们可以按照micro插件来进行编译。micro框架中的protobuf插件,我们需要单独安装。
-
安装micro框架的protobuf插件
go get github.com/micro/protobuf/proto go get github.com/micro/protobuf/protoc-gen-go
-
指定micro插件进行编译
protoc --go_out=plugins=micro:. message.proto
3、编码实现服务功能
在项目目录下,实现StudentService定义的rpc GetStudent功能。新建server.go文件,具体实现如下:
//学生服务管理实现 type StudentManager struct { } //获取学生信息的服务接口实现 func GetStudent(ctx context.Context, request *message.StudentRequest, response *message.Student) error { studentMap := map[string]message.Student{ "davie": message.Student{Name: "davie", Classes: "软件工程专业", Grade: 80}, "steven": message.Student{Name: "steven", Classes: "计算机科学与技术", Grade: 90}, "tony": message.Student{Name: "tony", Classes: "计算机网络工程", Grade: 85}, "jack": message.Student{Name: "jack", Classes: "工商管理", Grade: 96}, } if request.Name == "" { return errors.New(" 请求参数错误,请重新请求。") } student := studentMap[request.Name] if student.Name != "" { response = &student } return errors.New(" 未查询当相关学生信息 ") }
运行服务
在之前的学习过程中,我们是通过自己编写server.go程序,注册服务,并实现请求的监听。现在,我们用micro框架来实现服务的运行。完整的运行服务的代码如下:
func main() { service := micro.NewService(micro.Name("student_service"), micro.Version("1.0.0")) // 初始化 service.Init() // 注册服务 message.RegisterStudentServiceHandler(service.Server(), new(StudentManager)) // 启动 err := service.Run() if err != nil { log.Fatal(err) } }
客户端调用
客户端可以构造请求对象,并访问对应的服务方法。具体方法实现如下:
func main() { service := micro.NewService( micro.Name("student.client"), ) service.Init() studentService := message.NewStudentServiceClient("student_service", service.Client()) res, err := studentService.GetStudent(context.TODO(), &message.StudentRequest{Name: "davie"}) if err != nil { fmt.Println(err) return } fmt.Println(res.Name) fmt.Println(res.Classes) fmt.Println(res.Grade) }
运行结果
运行服务端
运行server.go文件中的main函数,服务注册成功,并输出如下日志:
2019/08/26 22:50:18 Transport [http] Listening on [::]:54343 2019/08/26 22:50:18 Broker [http] Connected to [::]:54344 2019/08/26 22:50:19 Registry [mdns] Registering node: student_service-346b454c-998d-4e85-a8cc-befbc0198eef
运行客户端
客户端负责发起请求和功能调用,运行client.go程序,程序正常输出。
etcd undefined: resolver.BuildOption
若在运行是发生以上错误,参考链接https://blog.csdn.net/qq_43442524/article/details/104997539
注册服务到consul
默认注册到mdns
在我们运行服务端的程序时,我们可以看到Registry [mdns] Registering node:xxx这个日志,该日志显示go-micro框架将我们的服务使用默认的配置注册到了mdns中。mdns是可简单翻译为mdns,是go-micro的默认配置选项。
注册到consul
在前面的微服务理论课程中,我们已经学习过consul。consul是服务注册与发现的组件,因此,如果我们本地系统已经安装了consul环境,我们可以选择将我们的服务注册到consul中。指定注册到consul时,需要先将consul进行启动。
启动consul
启动命令如下:consul agent -dev
通过上述命令,我们可以在终端中启动consul。
通过实例化一个registry注册到consul
consulRegistry := consul.NewRegistry(registry.Addrs("localhost:8500")) service := micro.NewService(micro.Name("student_service"), micro.Version("1.0.0"), micro.Registry(consulRegistry))
完整代码
server.go
package main import ( "GoCode/example/goMicroDemo/message" "context" "errors" "fmt" "github.com/micro/go-micro" "github.com/micro/go-micro/registry" "github.com/micro/go-plugins/registry/consul" "log" ) //学生服务管理实现 type StudentManager struct { } func (s StudentManager) GetStudent(c context.Context, request *message.StudentRequest, student *message.Student) error { studentMap := map[string]message.Student{ "davie": {Name: "davie", Classes: "软件工程专业", Grade: 80}, "steven": {Name: "steven", Classes: "计算机科学与技术", Grade: 90}, "tony": {Name: "tony", Classes: "计算机网络工程", Grade: 85}, "jack": {Name: "jack", Classes: "工商管理", Grade: 96}, } if request.Name == "" { return errors.New(" 请求参数错误,请重新请求。") } fmt.Println(request.Name) studentInfo := studentMap[request.Name] fmt.Println(studentInfo) if studentInfo.Name != "" { *student = studentInfo return nil } return errors.New(" 未查询当相关学生信息 ") } func main() { consulRegistry := consul.NewRegistry(registry.Addrs("localhost:8500")) service := micro.NewService(micro.Name("student_service"), micro.Version("1.0.0"), micro.Registry(consulRegistry)) // 初始化 service.Init() // 注册服务 message.RegisterStudentServiceHandler(service.Server(), new(StudentManager)) // 启动 err := service.Run() if err != nil { log.Fatal(err) } }
client.go
package main import ( "GoCode/example/goMicroDemo/message" "context" "fmt" "github.com/micro/go-micro" ) func main() { service := micro.NewService( micro.Name("student_client"), ) service.Init() studentService := message.NewStudentServiceClient("student_service", service.Client()) res, err := studentService.GetStudent(context.TODO(), &message.StudentRequest{Name: "davie"}) if err != nil { fmt.Println(err) return } fmt.Println(res.Name) fmt.Println(res.Classes) fmt.Println(res.Grade) }
参考链接
源码地址
更多相关内容 -
nacos-plugin:使用nacos-sdk-go的go-micro注册表插件
2021-03-16 14:41:34nacos插件 使用nacos-sdk-go的go-micro注册表插件 -
Go-golang-micro-benchmarks-Go的微基准测试小集合
2019-08-14 04:02:48golang-micro-benchmarks - Go的微基准测试小集合。 目的是比较一些语言特性 -
Go-基于微服务框架go-micro封装的go微服务脚手架
2019-08-14 02:16:13基于微服务框架go-micro 封装的go微服务脚手架 -
go-micro:go-microv2稳定版
2021-03-22 00:31:00Go Micro是用于分布式系统开发的框架。 它也被我们用来实现和支撑了百万级同时在线用户的业务。 服务治理能力,具体来说就是 发布部署,管理服务上下线和生命周期 服务注册与发现,有一个层次的地方能管控所有的... -
「go-micro」学习笔记1——Micro 与 Go-Micro
2020-10-28 10:22:05micro new helloworld 服务的启动与运行 # 在本地运行该服务并确保其正常工作. # 启动服务器 micro server # 设置为本地环境 micro env set local # 启动你的服务 micro run helloworld 服务状态 # 检查状态 ...Micro与Go-mirco
Micro 概述
Micro is a platform for cloud native development.
Micro是一个微服务工具包,包括:
API
提供并将HTTP请求路由到相应微服务的API网关。它充当微服务访问的单一入口,将HTTP请求转换为RPC并转发给相应的服务也可以用作反向代理。
Web
UI是go-micro的web版本,允许通过UI交互访问环境。在未来,它也将是一种聚合微型Web服务的方式。它包含一种Web应用程序的代理方式。将/[name]通过注册表路由到相应的服务。Web UI将前缀“go.micro.web。”(可以配置)添加到名称中,在注册表中查找它,然后将进行反向代理。
Sidecar
go-micro的HTTP接口版本。这是将非Go应用程序集成到微环境中的一种方式。
Bot
Hubot风格的bot,位于您的微服务平台中,可以通过Slack,HipChat,XMPP等进行交互。它通过消息传递提供CLI的功能。可以添加其他命令来自动执行常见的操作任务。
CLI
一个直接的命令行界面来与你的微服务进行交互,它提供了一种观察和与运行环境交互的方式。
Go-Micro
用于在Go中编写微服务的插件式RPC框架。它提供了用于服务发现,客户端负载平衡,编码,同步和异步通信库。go-micro 是一个独立的库,可以独立于其他工具包使用。
go-micro是组件化的框架,每一个基础功能都是一个interface,方便扩展。同时,组件又是分层的,上层基于下层功能向上提供服务,整体构成go-micro框架。go-micro框架的构成组件有:Registry
提供服务发现机制:解析服务名字至服务地址。目前支持的注册中心有consul、etcd、 zookeeper、dns、gossip等
Selector
选择器通过选择提供负载均衡机制。当客户端向服务器发出请求时,它将首先查询服务的注册表。这通常会返回一个表示服务的正在运行的节点列表。选择器将选择这些节点中的一个用于查询。多次调用选择器将允许使用平衡算法。目前的方法是循环法,随机哈希和黑名单。
Broker
发布和订阅的可插入接口,服务之间基于消息中间件的异步通信方式,默认使用http方式,线上通常使用消息中间件,如Nats、Kafka、RabbitMQ 和 http(用于开发)。
Transport
通过点对点传输消息的可插拔接口。目前的实现是http,rabbitmq和nats。通过提供这种抽象,运输可以无缝地换出。。
Codec
服务之间消息的编码/解码。
Plugins
提供go-micro的micro/go-plugins插件。
Server
服务器是构建正在运行的微服务的接口。它提供了一种提供RPC请求的方法。该组件基于上面的Registry/Selector/Transport/Broker组件,对外提供一个统一的服务请求入口。
Client
提供一种制作RPC查询的方法访问微服务的客户端。它结合了注册表,选择器,代理和传输。它还提供重试,超时,使用上下文等。类似Server组件,它也是通过Registry/Selector/Transport/Broker组件实现查找服务、负载均衡、同步通信、异步消息等功能。
总结
go-micro 是一个微服务的框架,而micro是官方提供的一个包,它是通过编译后的可执行文件来协助我们开发。
-
go微服务-go-micro框架介绍
2022-02-28 14:46:18文章目录go-micro框架介绍一、micro框架介绍1.1、背景1.2、概述1.3、micro组成1.4、工具包介绍1.4.1、API1.4.2、Web1.4.3、Sidecar1.4.4、Bot1.4.5、CLI1.4.6、Go-Micro1.5、Go-Micro特性1.6、环境安装1.6.1、安装...go-micro框架介绍
一、micro框架介绍
1.1、背景
在前面的内容中,我们已经学习了微服务之间通信采用的通信协议,如何实现服务的注册和发现,搭建服务管理集群,以及服务与服务之间的RPC通信方式。具体的内容包括:protobuf协议,consul及docker部署consul集群,gRPC框架的使用等具体的实现方案。
以上这些具体的方案都是为了解决微服务实践过程中具体的某个问题而提出的,实现微服务架构的项目开发。但是,在具体的项目开发过程中,开发者聚焦的是业务逻辑的开发和功能的实现,大量的环境配置,调试搭建等基础性工作会耗费相当一部分的精力,因此有必要将微服务架构中所涉及到的,相关的解决方案做集中管理和维护。这就是我们要学习的Micro。
1.2、概述
Micro是一个简化分布式开发的微服务生态系统,该系统为开发分布式应用程序提供了高效,便捷的模块构建。主要目的是简化分布式系统的开发。
学习完该框架以后,可以方便开发者们非常简单的开发出微服务架构的项目,并且随着业务模块的增加和功能的增加,Micro还能够提供管理微服务环境的工具和功能。
1.3、micro组成
micro是一个微服务工具包,是由一系列的工具包组成的,如下图所示:
-
Go Micro:
用于在Go中编写微服务的插件式RPC框架。它提供了用于服务发现,客户端负载平衡,编码,同步和异步通信库。 -
API:
API主要负责提供将HTTP请求路由到相应微服务的API网关。它充当单个入口点,可以用作反向代理或将HTTP请求转换为RPC。 -
Sidecar:
一种对语言透明的RPC代理,具有go-micro作为HTTP端点的所有功能。虽然Go是构建微服务的伟大语言,但您也可能希望使用其他语言,因此Sidecar提供了一种将其他应用程序集成到Micro世界的方法。 -
Web:
用于Micro Web应用程序的仪表板和反向代理。我们认为应该基于微服务建立web应用,因此被视为微服务领域的一等公民。它的行为非常像API反向代理,但也包括对web sockets的支持。 -
CLI:
一个直接的命令行界面来与你的微服务进行交互。它还使您可以利用Sidecar作为代理,您可能不想直接连接到服务注册表。 -
Bot:
Hubot风格的bot,位于您的微服务平台中,可以通过Slack,HipChat,XMPP等进行交互。它通过消息传递提供CLI的功能。可以添加其他命令来自动执行常见的操作任务。
1.4、工具包介绍
1.4.1、API
启用API作为一个网关或代理,来作为微服务访问的单一入口。它应该在您的基础架构的边缘运行。它将HTTP请求转换为RPC并转发给相应的服务。
1.4.2、Web
UI是go-micro的web版本,允许通过UI交互访问环境。在未来,它也将是一种聚合Micro Web服务的方式。它包含一种Web应用程序的代理方式。将/[name]通过注册表路由到相应的服务。Web UI将前缀“go.micro.web。”(可以配置)添加到名称中,在注册表中查找它,然后将进行反向代理。
1.4.3、Sidecar
该Sidecar是go-micro的HTTP接口版本。这是将非Go应用程序集成到Micro环境中的一种方式。
1.4.4、Bot
Bot是一个Hubot风格的工具,位于您的微服务平台中,可以通过Slack,HipChat,XMPP等进行交互。它通过消息传递提供CLI的功能。可以添加其他命令来自动执行常用操作任务。
1.4.5、CLI
Micro CLI是go-micro的命令行版本,它提供了一种观察和与运行环境交互的方式。
1.4.6、Go-Micro
Go-micro是微服务的独立RPC框架。它是该工具包的核心,并受到上述所有组件的影响。在这里,我们将看看go-micro的每个特征。
1.5、Go-Micro特性
-
Registry:主要负责服务注册和发现功能。我们之前学习过的consul,就可以和此处的Registry结合起来,实现服务的发现功能。
-
Selector:selector主要的作用是实现服务的负载均衡功能。当某个客户端发起请求时,将首先查询服务注册表,返回当前系统中可用的服务列表,然后从中选择其中一个节点进行查询,保证节点可用。
-
Broker:Broker是go-micro框架中事件发布和订阅的接口,主要是用消息队列的方式实现信息的接收和发布,用于处理系统间的异步功能。
-
Codec:go-micro中数据传输过程中的编码和解码接口。go-micro中有多重编码方式,默认的实现方式是protobuf,除此之外,还有json等格式。
-
Transport:go-micro框架中的通信接口,有很多的实现方案可以选择,默认使用的是http形式的通信方式,除此以外,还有grpc等通信方式。
-
Client和Server:分别是go-micro中的客户端接口和服务端接口。client负责调用,server负责等待请求处理。
1.6、环境安装
1.6.1、安装consul
consul环境是go-micro默认使用的服务发现方式。在之前的课程中已经安装过。
1.6.2、安装protobuf和依赖
关于protobuf相关知识,我们之前也已经安装并学习过,此处不再赘述。
1.6.3、micro工具包安装(可选择)
前面说过,micro是一个微服务系统,提供了很多工具包,可以帮助我们进行开发和调试。
可以使用如下命令安装micro的一系列的工具包:
go get -u github.com/micro/micro
1.6.4、1Go-micro安装
使用go-micro框架之前,首先需要安装go-micro框架,使用如下命令:
go get github.com/micro/go-micro
go-micro的源码在github上可以找到,链接如下:https://github.com/micro/go-micro
二、创建微服务
2.1、服务的定义
在micro框架中,服务用接口来进行定义,服务被定义为Service,完整的接口定义如下:
type Service interface { Init(...Option) Options() Options Client() client.Client Server() server.Server Run() error String() string }
在该接口中,定义了一个服务实例具体要包含的方法,分别是:Init、Options、Client、Server、Run、String等6个方法。
2.2、初始化服务实例
micro框架,除了提供Service的定义外,提供创建服务实例的方法供开发者调用:
service := micro.NewService()
如上是最简单一种创建service实例的方式。NewService可以接受一个Options类型的可选项参数。NewService的定义如下:
func NewService(opts ...Option) Service { return newService(opts...) }
2.2.1、Options可选项配置
关于Options可配置选项,有很多可以选择的设置项。micro框架包中包含了options.go文件,定义了详细的可选项配置的内容。最基本常见的配置项有:服务名称,服务的版本,服务的地址,服务:
//服务名称 func Name(n string) Option { return func(o *Options) { o.Server.Init(server.Name(n)) } } //服务版本 func Version(v string) Option { return func(o *Options) { o.Server.Init(server.Version(v)) } } //服务部署地址 func Address(addr string) Option { return func(o *Options) { o.Server.Init(server.Address(addr)) } } //元数据项设置 func Metadata(md map[string]string) Option { return func(o *Options) { o.Server.Init(server.Metadata(md)) } }
完整的实例化对象代码如下所示:
func main() { //创建一个新的服务对象实例 service := micro.NewService( micro.Name("helloservice"), micro.Version("v1.0.0"), ) }
开发者可以直接调用micro.Name为服务设置名称,设置版本号等信息。在对应的函数内部,调用了server.Server.Init函数对配置项进行初始化。
2.3、定义服务接口,实现服务业务逻辑
在前面的课程中,已经学习掌握了使用protobuf定义服务接口,并对服务进行具体实现。使用protobuf定义服务接口并自动生成go语言文件,需要经过以下几个步骤,我们通过示例进行说明:
我们依然通过案例来讲解相关的知识点:在学校的教务系统中,有学生信息管理的需求。学生信息包含学生姓名,学生班级,学习成绩组成;可以根据学生姓名查询学生的相关信息,我们通过rpc调用和学生服务来实现该案例。
2.3.1、定义.proto文件
使用proto3语法定义数据结构体和服务方法。具体定义内容如下:
syntax = 'proto3'; package message; option go_package="./;message"; //学生数据体 message Student { string name = 1; //姓名 string classes = 2; //班级 int32 grade = 3; //分数 } //请求数据体定义 message StudentRequest { string name = 1; } //学生服务 service StudentService { //查询学生信息服务 rpc GetStudent (StudentRequest) returns (Student); }
2.3.2、编译.proto文件
在原来学习gRPC框架时,我们是将.proto文件按照grpc插件的标准来进行编译。而现在,我们学习的是go-micro,因此我们可以按照micro插件来进行编译。micro框架中的protobuf插件,我们需要单独安装。
-
安装micro框架的protobuf插件
go get -u github.com/micro/protoc-gen-micro
-
指定micro插件进行编译
protoc --proto_path=. --micro_out=. --go_out=. message.proto
上述编译命令执行成功,可以在项目目录下的message目录下生成message.pb.go文件,该文件是由protoc编译器自动编译生成,开发者不能修改。message.pb.go如图所示:
2.3.3、编码实现服务功能
在项目目录下,实现StudentService定义的rpc GetStudent功能。新建studentManager.go文件,具体实现如下:
//学生服务管理实现 type StudentManager struct { } //获取学生信息的服务接口实现 func GetStudent(ctx context.Context, request *message.StudentRequest, response *message.Student) error { studentMap := map[string]message.Student{ "davie": message.Student{Name: "davie", Classes: "软件工程专业", Grade: 80}, "steven": message.Student{Name: "steven", Classes: "计算机科学与技术", Grade: 90}, "tony": message.Student{Name: "tony", Classes: "计算机网络工程", Grade: 85}, "jack": message.Student{Name: "jack", Classes: "工商管理", Grade: 96}, } if request.Name == "" { return errors.New(" 请求参数错误,请重新请求。") } student := studentMap[request.Name] if student.Name != "" { response = &student } return errors.New(" 未查询当相关学生信息 ") }
2.4、运行服务
在之前的学习过程中,我们是通过自己编写server.go程序,注册服务,并实现请求的监听。现在,我们用micro框架来实现服务的运行。完整的运行服务的代码如下:
func main() { //创建一个新的服务对象实例 service := micro.NewService( micro.Name("student_service"), micro.Version("v1.0.0"), ) //服务初始化 service.Init() //注册 message.RegisterStudentServiceHandler(service.Server(), new(StudentManager)) //运行 err := service.Run() if err != nil { log.Fatal(err) } }
2.5、客户端调用
客户端可以构造请求对象,并访问对应的服务方法。具体方法实现如下:
func main() { service := micro.NewService( micro.Name("student.client"), ) service.Init() studentService := message.NewStudentServiceClient("student_service", service.Client()) res, err := studentService.GetStudent(context.TODO(), &message.StudentRequest{Name: "davie"}) if err != nil { fmt.Println(err) } fmt.Println(res.Name) fmt.Println(res.Classes) fmt.Println(res.Grade) }
注意
go-micro的版本非常混乱
出现问题:
panic: qtls.ConnectionState not compatible with tls.ConnectionState
解决方案:降低go的版本,降至1.13
2.6、运行结果
2.6.1、运行服务端
运行main.go文件中的main函数,服务注册成功,并输出如下日志:
2019/08/26 22:50:18 Transport [http] Listening on [::]:54343 2019/08/26 22:50:18 Broker [http] Connected to [::]:54344 2019/08/26 22:50:19 Registry [mdns] Registering node: student_service-346b454c-998d-4e85-a8cc-befbc0198eef
2.6.2、运行客户端
客户端负责发起请求和功能调用,运行client.go程序,程序正常输出。
2.7、注册服务到consul
2.7.1、默认注册到mdns
在我们运行服务端的程序时,我们可以看到Registry [mdns] Registering node:xxx这个日志,该日志显示go-micro框架将我们的服务使用默认的配置注册到了mdns中。mdns是可简单翻译为mdns,是go-micro的默认配置选项。
2.7.2、注册到consul
在前面的微服务理论课程中,我们已经学习过consul。consul是服务注册与发现的组件,因此,如果我们本地系统已经安装了consul环境,我们可以选择将我们的服务注册到consul中。指定注册到consul时,需要先将consul进行启动。
-
启动consul
启动命令如下:consul agent -dev
通过上述命令,我们可以在终端中启动consul。
- 指定服务注册到consul
通过命令运行服务程序,并指定注册到consul,详细命令如下:
go run main.go --registry=consul
通过–registry选项,指定要注册到的服务发现组件。
-
查看服务
由于consul给我们提供了ui界面,因此我们可以通过浏览器界面来访问consul节点页面。访问本地8500端口,浏览器地址是:http://localhost:8500
在创建微服务的时候也可以使用
micro.Registry(consul.NewRegistry()),
的方式指定使用consul作为服务发现组件:service := micro.NewService( // 虽然consul有默认端口,但是我们最好自己声明一个端口 micro.Address("127.0.0.1:12341"), micro.Name("studentService"), micro.Registry(consul.NewRegistry()), }
在此之前需要拉取consul插件:
go get github.com/micro/go-plugins/registry/consul
-
-
go-secbuy-micro:基于Go-micro微服务的秒杀系统
2021-03-11 16:57:24基于Go-micro微服务的秒杀系统 系统架构 一个经典的秒杀场景可以分为如下几个步骤 创建商品的库存信息 检查库存数量,满足数量就扣库存,否则失败 成功扣取库存后创建订单 创建支付记录 依据这个流程,系统分为如下... -
go-micro v2 hello-micro
2021-10-10 13:56:40go-micro v2入门到精通—1 使用go-micro 创建第一个web api 实现代码如下: package main import ( "github.com/micro/go-micro/v2/web" "net/http" ) func main(){ server := web.NewService(web.Address(":...go-micro v2入门到精通—1
使用go-micro 创建第一个web api
实现代码如下:
package main import ( "github.com/micro/go-micro/v2/web" "net/http" ) func main(){ server := web.NewService(web.Address(":8777")) server.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte("hello world")) }) server.Run() }
运行之后打开浏览器:访问 http://127.0.0.1:8777/ 我们会看见页面输出 hello word
引入gin框架生成web api
在我们项目中使用 micro 提供的API 服务来做项目,而gin框架作为web服务器的热门框架相对于灵活很多。
package main import ( "github.com/gin-gonic/gin" "github.com/micro/go-micro/v2/web" ) func main(){ //声明gin web路由 router := gin.Default() router.Handle("GET","/news", func(context *gin.Context) { context.String(200,"news hello") }) router.Handle("GET","/test", func(context *gin.Context) { context.String(200,"test hello") }) //添加处理gin路由 server := web.NewService(web.Address(":8777"),web.Handler(router)) server.Run() }
consul服务发现治理
首先我们来看以下这张图片
图中,客户端的一个接口,需要调用服务A-N。客户端必须要知道所有服务的网络位置的,以往的做法是配置是配置文件中,或者有些配置在数据库中。这里就带出几个问题:- 需要配置N个服务的网络位置,加大配置的复杂性
- 服务的网络位置变化,都需要改变每个调用者的配置
- 集群的情况下,难以做负载(反向代理的方式除外)
总结起来一句话:服务多了,配置很麻烦,问题多多。
既然有这些问题,那么服务发现就是解决这些问题的。话说,怎么解决呢?我们再看一张图
与之前一张不同的是,加了个服务发现模块。图比较简单,这边文字描述下。服务A-N把当前自己的网络位置注册到服务发现模块(这里注册的意思就是告诉),服务发现就以K-V的方式记录下,K一般是服务名,V就是IP:PORT。服务发现模块定时的轮询查看这些服务能不能访问的了(这就是健康检查)。客户端在调用服务A-N的时候,就跑去服务发现模块问下它们的网络位置,然后再调用它们的服务。这样的方式是不是就可以解决上面的问题了呢?客户端完全不需要记录这些服务网络位置,客户端和服务端完全解耦!
这个过程大体是这样,当然服务发现模块没这么简单。里面包含的东西还很多。这样表述只是方便理解。consul 安装
consul官网: 传送门.
启动consul
consul agent -dev -client=0.0.0.0
consul 实现服务治理
具体的安装以及启动过程我就不做赘述了,可自行百度。
服务端代码实现package main import ( "fmt" "github.com/gin-gonic/gin" "github.com/micro/go-micro/v2/registry" "github.com/micro/go-micro/v2/web" "github.com/micro/go-plugins/registry/consul/v2" ) func main() { router := gin.Default() router.Handle("POST","/news", func(context *gin.Context) { context.JSON(200,gin.H{ "data":"index", }) }) registry := consul.NewRegistry(registry.Addrs("127.0.0.1:8500")) server := web.NewService( web.Name("helloworld"), //web.Address(":8082"), web.Handler(router), web.Registry(registry), web.Metadata(map[string]string{"protocol" : "http"}),//需要声明协议,否则导致无法调用 ) server.Init() //使用Init 函数 可接收flags参数 err := server.Run() fmt.Println(err) }
这里为了更好的演示效果,我们分别开启3个服务,编写run.bat 写入以下代码
@echo off start "server1" go run main.go --server_address :8001 & start "server2" go run main.go --server_address :8002 & start "server3" go run main.go --server_address :8003 pause
直接双击执行,我们在consul的web管理中,可以看到有3个服务实例
现在我们再来编写服务发现端,服务发现端,只是做了一个流量转发而已。package main import ( "context" "encoding/json" "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/client/selector" "github.com/micro/go-micro/v2/registry" "github.com/micro/go-micro/v2/web" microhttp "github.com/micro/go-plugins/client/http/v2" "github.com/micro/go-plugins/registry/consul/v2" "io" "io/ioutil" "net/http" "strings" ) func main() { cr := consul.NewRegistry(registry.Addrs("127.0.0.1:8500")) st := selector.NewSelector( selector.Registry(cr), selector.SetStrategy(selector.RoundRobin), ) server := web.NewService(web.Address(":8777")) server.HandleFunc("/news", func(writer http.ResponseWriter, request *http.Request) { resps,_ := callByGoPlugin(st,"/news") res,_ := json.Marshal(resps) writer.Write(res) }) server.Run() } func callByGoPlugin(s selector.Selector,path string) (map[string]interface{}, error) { // 1. 调用`go-plugins/client/http`包的函数获取它们提供的httpClient gopluginClient := microhttp.NewClient( client.Selector(s), // 传入上面的selector client.ContentType("application/json"), // 指定contentType ) // 2. 新建请求对象,传入: (1)服务名 (2)endpoint (3)请求参数 req := gopluginClient.NewRequest("helloworld", path, nil) // 3. 新建响应对象,并call请求,获取响应 var resp map[string]interface{} err := gopluginClient.Call(context.Background(), req, &resp) if err != nil { return nil, err } return resp, nil } func RequestApi(method string, host string, path string, body io.Reader) (string, error) { // 1.如果没有http开头就给它加一个 if !strings.HasPrefix(host, "http://") && !strings.HasPrefix(host, "https://") { host = "http://" + host } // 2. 新建一个request req, _ := http.NewRequest(method, host+path, body) // 3. 新建httpclient,并且传入request client := http.DefaultClient res, err := client.Do(req) if err != nil { return "", err } defer res.Body.Close() // 4. 获取请求结果 buff, err := ioutil.ReadAll(res.Body) if err != nil { return "", err } return string(buff), nil }
-
mega-go-micro:基于go-micro v2封装的golang微服务框架,请谨慎使用
2021-03-30 18:19:08基础组件服务 提供mysql,redis,mongo.consul,kafka...go get github.com/hammercui/mega-go-micro 常问问题 1 etcd err:go mod使用gprc 1.26.0 replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 -
Go-Micro微服务框架使用
2020-12-09 23:54:421.Go-Micro微服务框架简介 Go-Micro类似Java中的SpringCloud,虽然生态上...Golang本身提供了丰富的http包,并且Gin等Web框架实现一个Web服务,但是为了贴合Go-Micro框架的统一规范,所以需要通过使用Go-Micro的github. -
go-micro
2020-12-27 12:57:59由于go语言和go-micro框架迭代迅速,我在学习go-micro框架查询资料时,经常因为过时的资料遇到莫名其妙的错误。因此我决心根据自己的实践与摸索,编写一个适合go-micro V2版本切实可用的go-micro开发指南,重点记录... -
go 微服务之go-micro v3+gin
2022-01-03 19:43:23安装gin go get -u github.com/gin-gonic/gin 安装go-micro v3 先安装依赖 go get -u github....//安装asim/go-micro 这个是go micro 3.0 框架 go get github.com/asim/go-micro/cmd/protoc-gen-micro/v3 安装m -
[从RPC到Go-Micro 捌]Go-Micro解耦利器--事件驱动机制
2020-11-10 23:50:05之前的文章中我们已经学习了使用go-micro创建微服务,并实现了服务的调用。我们具体的实现是实例化了client对象,并调用了对应服务的相关方法。这种方式可以实现系统功能,但有比较大的缺点。 我们通过举例来说明:... -
Go微服务——go-micro v4安装
2022-03-20 12:32:24go-micro 安装 go-micro 服务端 go-micro 客户端(gin框架调用微服务) go-micro+consul服务注册、服务发现 1.介绍 go-micro网站:https://github.com/asim/go-micro 现在最新的已经到了v4版本,如下图 注意: ... -
go微服务学习 go-micro框架-—— micro安装
2021-11-01 03:18:25由于 Micro3.0直接放弃维护 go-micro,所以网上很多文章都是已经过时的了。那些安装方法根本装不上了。此贴主要根据官方文档进行摸索,感觉官方文档似乎也没来得及更新,所以部分操作也没能成功。就只记录一下自己... -
基于知名微服务框架go-micro开发gRPC应用程序
2022-04-21 07:14:29go-micro是golang的一个微服务框架。这篇文章将介绍使用go-micro最新版本v4开发gRPC服务的方式。 -
【Go语言实战】 (10) go-micro微服务 实现简单备忘录 (上) | 用户模块
2022-01-03 14:08:29下载1.1 go-micro/v21.2 protoc1.3 protobuf2. 用户模块2.1 数据库配置2.2 proto文件编写2.3 实现用户模块业务逻辑2.3.1 用户注册方法2.3.2 登录服务方法2.4 接入etcd服务发现3. 接入网关3.1 proto文件3.2 接入路由... -
go-micro examples 中noproto 代码学习(go-micro 中微服务使用json格式 来传输)
2021-01-20 13:32:26go- micro 中微服务 都可以使用哪些 传输协议? go -micro 中 微服务中 我不想使用 protobuf 协议,或者在微服务中,我就想使用json 格式来传输 编码? 目录: main.go 代码如下: package main import ( context... -
Go-lang分布式框架选择上的历程记录【go-micro、go-zero、go-kratos】
2022-04-29 13:13:11go-micro,最近变动很大,分布式框架的这个分支不确定后续还能得到创作者多少支持,暂时观望。 go-kratos,学了几天,发现这个源码应该是写得不错的,但是文档教程部分似乎无人管理。有些东西源码里变动了但官方文档... -
go-micro 入门教程1.搭建 go-micro环境
2019-08-19 16:29:10go-micro是基于golang的微服务编程框架,go-micro操作简单、编码高效、功能强大。但是网络上资料偏少,本系列文章定位最简单最容易上手的go-micro入门教程,所有案列来自实操,而非网络上的复制粘贴。 本章节的... -
MICRO和GO-MICRO
2021-11-26 18:01:17createdtime 20211124 updatedtime 20211126 ...micro是基于go-micro编写,面向go-micro服务治理与生态的工具集,它包含很多服务和工具。 micro和go-micro之间的关系是什么? ①micro与go-micro是两个.. -
GO-micro入门
2022-03-24 22:57:14Micro是什么? 是用来构建和管理分布式程序的系统 Runtime(运行时):用来管理配置,认证,网络等 Framework(程序开发框架):用来方便编写微服务 Clients(多语言客户端):支持多语言访问客户端 ... -
go微服务学习 go-micro框架(一)
2021-10-30 02:27:29在了解go-micro之前,我们先来了解一下什么是micro。 Micro解决了在云内外构建分布式系统的关键要求。它利用微服务体系结构模式,并提供一组作为平台构建基块的服务. Micro 处理分布式系统的复杂性,并提供更简单的... -
go-micro的安装问题
2022-04-03 21:42:38安装go-micro出现的问题 问题描述 使用命令go get -u -v github.com/micro/go-micro(如果你这个可以的话,下面的就不用看了) 报错fatal: unable to access 'https://github.com/micro/go-micro/': OpenSSL SSL_re... -
go-micro 微服务开发
2021-08-29 11:26:48Micro概述 Micro是一个简化分布式开发的微服务生态系统。它为开发分布式应用程序提供了基本的构建模块。 什么是Micro? Micro是一个微服务生态系统,致力于提供产品,服务和解决方案,以实现现代软件驱动型企业的... -
go-micro集成链路跟踪的方法和中间件原理
2022-05-05 07:36:42前几天有个同学想了解下如何在go-micro中做链路跟踪,这几天正好看到wrapper这块,wrapper这个东西在某些框架中也称为中间件,里边有个opentracing的插件,正好用来做链路追踪。opentracing是个规范,还需要搭配一个... -
golang微服务框架go-micro 入门笔记2.4 go-micro service解读
2019-09-17 08:11:49本章节阐述go-micro 服务发现原理 go-micro架构 下图来自go-micro官方 阅读本文前你可能需要...golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架go-micro 入门笔记2.1 micro工具之... -
初识go-micro
2020-12-21 10:42:16简介 ...学习rpc与grpc https://www.liwenzhou.com/posts/Go/gRPC/ 学习etcd https://www.liwenzhou.com/posts/Go/go_etcd/ 学习protobuf ...go get github.com/micro/go-micro/v -
go-micro开发RPC服务的方法及其运行原理
2022-04-24 12:41:39优质资源分享 ...知识定位 人群定位 ... Python实战微信订餐小程序 ...go-micro是一个知名的golang微服务框架,最新版本是v4,这篇文章将介绍go-micro v4开发RPC服务的方法及其运作原理。 基本概念 go-micro