Go Micro框架

Go Micro是一个微服务开发框架。Go Micro提供了分布式系统开发的核心要求,包括RPC和事件驱动的通信。

特点

  • 自动服务注册与名称解析:服务发现是微服务开发中的核心,用于解析服务名与地址。consulGo Micro默认的服务发现注册中心。发现系统可插拔,其他插件像etcdkuberneteszookeeper
  • 负载均衡:在服务发现之上构建了负载均衡机制。使用随机处理过的哈希负载均衡机制来保证对服务请求颁布的均匀分布。
  • 消息编码:支持基于内容类型(content-type)动态编码消息。客户端和服务端会一起使用content-type格式来对Go进行无缝编/解码。content-type默认包含proto-rpcjson-rpc
  • Request/Response:RPC通信基于支持双向流的请求/响应方式,提供同步通信机制,请求发送到服务时,会自动解析,负载均衡,拨号,转成字节流。
  • 异步消息:发布订阅等功能内置在异步通信与事件驱动架构中,事件通知在微服务开发中处于核心位置。默认的消息传递使用点到点http/1.1,激活tls时则使用http2。
  • 可插拔接口:Go Micro为每个分布式系统抽象出接口,因此,Go Micro的接口都是可插拔的,允许其在运行时不可知的情况下仍可支持。

编写服务

服务原型

微服务中有个关键需求点,就是接口的强定义。Micro使用protobuf来完成这个需求。以gRPC使用简介文章中的服务为例,定义Greeter处理器,它有一个Hello方法。它有HelloRequest入参对象以及HelloResponse出参对象,两个对象都有一个字符串类型的参数。
helloworld.proto文件:

syntax = "proto3";

package main;

service Greeter {
    rpc Hello (HelloRequest) returns (HelloResponse) {
    }
}

message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string greeting = 2;
}

生成原型

在定义好原型后,我们使用protoc以及micro的插件来编译它,micro插件可以帮助生成go micro需要的原型文件。

protoc --proto_path=. --micro_out=. --go_out=. ./helloworld.proto

执行完命令后,将会在当前目录下生成helloworld.pb.go文件和helloworld.micro.go文件。
其中helloworld.micro.go文件中分别定义了Greeter服务的客户端API和服务端API,如下:

...
// Client API for Greeter service
type GreeterService interface {
	Hello(ctx context.Context, in *HelloRequest, opts ...client.CallOption) (*HelloResponse, error)
}

// Server API for Greeter service
type GreeterHandler interface {
	Hello(context.Context, *HelloRequest, *HelloResponse) error
}

编写服务

下方的代码是greeter服务的代码,它要实现下面的几个要求:

  1. 实现在GreeterHandler中定义的接口
  2. 初始化micro.Service
  3. 注册Greeter handler
  4. 运行服务

greeter_servermicro.go文件内容:

package main

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

type Greeter struct {
}

func (g *Greeter) Hello(ctx context.Context, req *HelloRequest, rsp *HelloResponse) error {
	rsp.Greeting = "hello" + req.Name
	return nil
}

func main() {
	// 创建新的服务,这里可以传入其他选项
	service := micro.NewService(micro.Name("greeter"))

	// 初始化方法会解析命令行标识
	service.Init()

	// 注册处理器
	err := RegisterGreeterHandler(service.Server(), new(Greeter))
	if err != nil {
		fmt.Println("failed to register a greeter handler: ", err)
	}

	// 运行服务
	if err = service.Run(); err != nil {
		fmt.Println("failed to run a service: ", err)
	}
}

运行服务

执行命令go run greeter_servermicro.go
输出

2019/04/29 13:39:41 Transport [http] Listening on [::]:54648
2019/04/29 13:39:41 Broker [http] Connected to [::]:54649
2019/04/29 13:39:41 Registry [mdns] Registering node: greeter-29622a6a-50b6-4ff9-b580-8ce1b7a52f5f

定义客户端

下面的客户端代码用来查询greeter服务,上面我们生成的proto原型文件中包含了客户端部分,这样可以减少模板代码量。
greeter_clientmicro.go文件

package main

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

func main() {
	// 定义服务,可以传入其他可选参数
	service := micro.NewService(micro.Name("greeter.client"))
	service.Init()

	// 创建新的客户端
	greeter := NewGreeterService("greeter", service.Client())

	// 调用greeter
	rsp, err := greeter.Hello(context.TODO(), &HelloRequest{Name: "benben_2015"})
	if err != nil {
		fmt.Println("failed to execute a greeter: ", err)
	}

	// 打印响应请求
	fmt.Println(rsp.Greeting)
}

运行客户端

执行命令go run greeter_clientmicro.go
输出

hello benben_2015

编写Function

Go Micro包含了函数式编程模型。Function是指接收一次请求,执行后便退出的服务。
greeter_funcmicro.go文件内容:

package main

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

type Greeter struct {
}

func (g *Greeter) Hello(ctx context.Context, req *HelloRequest, rsp *HelloResponse) error {
	rsp.Greeting = "hello" + req.Name
	return nil
}

func main() {
	// 创建新函数
	fnc := micro.NewFunction(micro.Name("greeter"))

	// 初始化命令行
	fnc.Init()

	// 注册handler
	err := fnc.Handle(new(Greeter))
	if err != nil {
		fmt.Println("failed to register a handler: ", err)
	}

	// 运行服务
	if err = fnc.Run(); err != nil {
		fmt.Println("failed to run a service: ", err)
	}
}

参考文章

  1. Go Micro

你可能感兴趣的:(GO学习总结)