微服务技术初探(go-micro)

微服务技术初探#

微服务概述#

微服务是近几年产生的新概念,与传统的单体式服务相比,微服务具有更好的扩展性及低耦合度等特性。微服务的重点在于服务的治理和调度。
微(micro):狭义来说就是体积小。
服务(service):区别于系统,服务一个或者一组相对较小且独立的功能单元,是用户可以感知最小功能集,比如用户注册服务、用户权限认证服务等。
微服务架构:微服务架构是将复杂的系统使用组件化的方式进行拆分,并用轻量级通讯方式进行整合的一种设计方法。可以用一句话描述“分而治之,合而用之”。
微服务架构风格:微服务架构风格是将单个应用程序作为一组小型服务开发的方法,每个服务程序都在自己的进程中运行,并与轻量级机制(比如HTTP API、RPC)进行通信,这些服务围绕业务功能构建,不同服务可以用不同的编程语言编写,数据存储也通常各自管理而不是集中式管理。
总结来说微服务是用微服务架构风格设计的应用。

go-micro学习微服务#

服务发现#

在做微服务开发的时候,客户端的一个接口可能需要调用N个服务,客户端必须知道所有服务的网络位置(ip+port),如:

vqwTFU.png

以往的做法是把服务的地址放在配置文件或数据库中,这样就有以下几个问题:

  • 需要配置N个服务的网络位置,加大配置的复杂性
  • 服务的网络位置变化,需要改变每个调用者的配置
  • 集群的情况下,难以做负载(反向代理的方式除外)

微服务里选择服务发现来解决这些问题。如:

vqwOyR.png

服务端把当前自己的网络位置注册到服务发现模块,服务发现就以K-V的方式记录下,K一般是服务名,V就是IP:PORT。服务发现模块定时的轮询查看这些服务能不能访问(健康检查)。客户端在调用服务A-N的时候,就跑去服务发现模块问下它们的网络位置,然后再调用它们的服务。这样客户端和服务端就解耦了!

常见的服务发现框架有:Etcd、Eureka、Consul、Zookeeper、Apollo

go-micro默认的服务发现框架是consul,在v2以后版本中默认的服务发现换成了etcd。

go-micro安装#

这里选择使用较多的v4版本

环境安装:

https://github.com/asim/go-micro

Copy
#安装go-micro go get -u -v github.com/micro/go-micro #安装工具集 go get -u -v github.com/micro/micro #dependence # protobuf安装 https://github.com/protocolbuffers/protobuf/releases # protoc-gen-go安装 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest # protoc-gen-micro安装 # go install github.com/micro/micro/v2/cmd/protoc-gen-micro@latest # go install github.com/micro/micro/v3/cmd/protoc-gen-micro@master go install github.com/go-micro/generator/cmd/protoc-gen-micro # 如果是windows要安装micro cli git clone https://github.com/go-micro/cli.git cd cmd/go-micro go build -o micro.exe 或者: https://github.com/go-micro/cli/tree/v1.1.1 ## 这里protoc-gen-micro我用的适配最新的https://github.com/GhostLuker/protoc-gen-micro protoc-gen-mymicro.exe protoc --proto_path=. --mymicro_out=. --go_out=:. proto/helloworld.proto

docker环境安装:

Copy
$ docker pull microhq/micro

go-micro创建个HelloWorld微服务#

Copy
# 创建微服务项目代码 go-micro new service helloworld # 初始化 cd helloworld (原本是make proto tidy,windows这里有点问题我就直接执行Makefile里的指令) protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto go mod tidy

这样一个微服务程序就初始化完成了。目录结构如下:

Copy
helloworld ├── Dockerfile ├── Makefile ├── go.mod ├── go.sum ├── handler │   └── helloworld.go ├── main.go └── proto ├── helloworld.pb.go ├── helloworld.pb.micro.go └── helloworld.proto

go run main.go 启动服务端后

可以使用命令行直接调用也可以手写客户端代码调用:

Copy
# 命令行调用 go-micro call helloworld Helloworld.Call "{\"name\": \"John\"}"

客户端代码调用示例:

Copy
package main import ( "context" "fmt" "go-micro.dev/v4" helloworld "helloworld/proto" ) /** 命令行调用micro服务服务的方法:go-micro call helloworld Helloworld.Call "{\"name\": \"John\"}" */ func main() { // create the greeter client using the service name and client serv := micro.NewService( micro.Name("helloworld"), micro.Version("latest"), ) serv.Init() //创建客户端 hello_client := helloworld.NewHelloworldService("helloworld", serv.Client()) //调用rpc服务 rsp, err := hello_client.Call(context.TODO(), &helloworld.CallRequest{Name: "Tom"}) if err != nil { fmt.Println(err) return } fmt.Println(rsp.GetMsg()) }

配合服务注册的go-micro示例#

如上是go-micro微服务框架生成的helloworld代码示例,下面测试下带有服务注册的helloworld示例,这里服务注册使用golang的神器etcd来实现。

ETCD的安装非常简单这里省略...

服务端代码

Copy
package main import ( "github.com/asim/go-micro/plugins/registry/etcd/v4" "go-micro.dev/v4/registry" "helloworld/handler" pb "helloworld/proto" "go-micro.dev/v4" log "go-micro.dev/v4/logger" ) var ( service = "helloworld" version = "latest" ) func main() { // Create service srv := micro.NewService( micro.Name(service), micro.Version(version), // etcd注册 micro.Registry(etcd.NewRegistry( registry.Addrs("127.0.0.1:2379"), )), ) srv.Init() // Register handler pb.RegisterHelloworldHandler(srv.Server(), new(handler.Helloworld)) // Run service if err := srv.Run(); err != nil { log.Fatal(err) } }

客户端代码:

Copy
package main import ( "context" "fmt" "github.com/asim/go-micro/plugins/registry/etcd/v4" "go-micro.dev/v4" "go-micro.dev/v4/registry" helloworld "helloworld/proto" ) /** 命令行调用micro服务服务的方法:go-micro call helloworld Helloworld.Call "{\"name\": \"John\"}" */ func main() { // create the greeter client using the service name and client serv := micro.NewService( micro.Name("helloworld"), micro.Version("latest"), micro.Registry(etcd.NewRegistry( registry.Addrs("127.0.0.1:2379"), )), ) serv.Init() //创建客户端 hello_client := helloworld.NewHelloworldService("helloworld", serv.Client()) //调用rpc服务 rsp, err := hello_client.Call(context.TODO(), &helloworld.CallRequest{Name: "Tom"}) if err != nil { fmt.Println(err) return } fmt.Println(rsp.GetMsg()) }

其实go-micro也可以通过命令行进行指定配置注册中心:

Copy
--registry=etcd --registry_address=172.18.0.58:2379

但是生产过程一般不这样使用,会增加部署的复杂性。

小结#

通过go-micro对微服务进行了简单的入门学习,go-micro框架的其它知识如: 服务发现、RPC客户/服务端、广播/订阅机制、API网关、链路追踪、超时容错、重试机制、负载均衡、等等待后续慢慢探索。

posted @   村口王铁匠  阅读(513)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示

目录

目录

×