go micro实战01:快速搭建服务

栏目: IT技术 · 发布时间: 5年前

内容简介:go-micro给我们提供了一个非常便捷的方式来快速搭建微服务,而且并不需要提前系统了解micro,下面用一个简单的示例来快速实现一个服务。因为我们要做微服务,那么就一定有服务端和客户端,这两个端通过什么格式进行内容传输,就涉及到了序列化,比较主流的序列化协议就是JSON和Protobuf,因为Protobuf是以二进制传输的,体积比较小,所以传输速度也相对较快,今天就以protobuf来进行演示。下面使用Proto3的语法在protos目录创建文件

背景

go-micro给我们提供了一个非常便捷的方式来快速搭建微服务,而且并不需要提前系统了解micro,下面用一个简单的示例来快速实现一个服务。

创建Proto文件

因为我们要做微服务,那么就一定有服务端和客户端,这两个端通过什么格式进行内容传输,就涉及到了序列化,比较主流的序列化协议就是JSON和Protobuf,因为Protobuf是以二进制传输的,体积比较小,所以传输速度也相对较快,今天就以protobuf来进行演示。

下面使用Proto3的语法在protos目录创建文件 greeter.proto ,该文件定义一个名为 Greeter 的服务,以及对应的入参和出参。

syntax = "proto3";
package protos;

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

message Request {
    string name = 1;
}

message Response {
    string greeting = 2;
}

生成 Go 文件

生成Go文件之前,要先确保本机安装了protobuf,如果在终端输入 protoc 没有打印出帮助文档,那么就是未安装。

$ protoc
Usage: protoc [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
  -IPATH, --proto_path=PATH   Specify the directory in which to search for
                              imports.  May be specified multiple times;
                              directories will be searched in order.  If not
                              ……

可以通过官方文档提示的命令进行安装。

go get github.com/micro/protoc-gen-micro/v2

安装成功之后,通过protoc命令将 greeter.proto 文件生成出对应的Go文件。

protoc --proto_path=./protos --micro_out=./protos --go_out=./protos ./protos/greeter.proto
  • --proto_path 是greeter.proto文件所在的路径

  • --micro_out 是生成 .go 文件的所在目录,该文件被用于创建服务

  • --go_out 是生成 .go 文件的所在目录,该文件被用于做数据序列化传输

可以根据需求自定义输出目录,我这边输出到了protos目录,现在可以看到protos目录中生成了两个文件。

greeter.pb.go
greeter.pb.micro.go

实现服务

因为刚才已经通过protobuf定义了服务的接口,所以接下来需要实现对应的服务。

第一步,实现定义的服务接口

在生成的 greeter.pb.micro.go 文件中,可以看到我们 greeter.proto 文件中一个名为 GreeterHandler 的接口。

type GreeterHandler interface {
	Hello(context.Context, *Request, *Response) error
}

我们需要先实现该接口,接下来创建server.go文件,定义结构体Greeter,并实现Hello方法。

type Greeter struct {
}

func (g *Greeter) Hello(context context.Context, req *protos.Request, rsp *protos.Response) error {
	rsp.Greeting = "Hello " + req.Name
	return nil
}

Hello方法的后两个参数刚好就是我们前面所生成的 greeter.bp.go 文件中定义的Request和Response结构体。在方法内部,将请求参数的Name前面拼接上了 Hello 字符串,并且赋值给了Response的Greeting变量。

第二步,初始化服务

我们创建一个名为 greeter 的服务。

func main() {
	service := micro.NewService(
		micro.Name("greeter"),
	)
	service.Init()
}

调用 micro.NewService 方法来创建一个新的服务,该方法的参数是可变参数,可以通过micro中的一系列方法来设置服务的参数,本次示例中只配置服务的名称,记得在创建完服务后执行 service.Init 方法来初始化,micro版本建议使用v2。

第三步,注册服务到handler

func main() {
	service := micro.NewService(
		micro.Name("greeter"),
	)
	service.Init()
	err := protos.RegisterGreeterHandler(service.Server(), new(Greeter))
	if err != nil {
		fmt.Println(err)
	}
}

第四步,将服务跑起来

if err := service.Run(); err != nil {
		fmt.Println(err)
	}

完整代码如下

package main

import (
	"context"
	"fmt"

	"github.com/micro/go-micro/v2"
)

type Greeter struct {
}

func (g *Greeter) Hello(context context.Context, req *Request, rsp *Response) error {
	rsp.Greeting = "Hello " + req.Name
	return nil
}

func main() {
	service := micro.NewService(
		micro.Name("greeter"),
	)
	service.Init()

	err := protos.RegisterGreeterHandler(service.Server(), new(Greeter))
	if err != nil {
		fmt.Println(err)
	}

	if err := service.Run(); err != nil {
		fmt.Println(err)
	}
}

现在将服务端跑起来。

$ go run server.go
2020-03-27 11:28:20 Starting [service] greeter
2020-03-27 11:28:20 Server [grpc] Listening on [::]:63763
2020-03-27 11:28:20 Registry [mdns] Registering node: greeter-8afc1183-a159-4473-a567-c13b83d1d75c

实现客户端

创建 client.go 文件

func main() {
	service := micro.NewService(micro.Name("greeter.client"))
	service.Init()

	greeter := protos.NewGreeterService("greeter", service.Client())
	rsp, err := greeter.Hello(context.TODO(), &protos.Request{Name: "pingye"})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(rsp.Greeting)
}

执行客户端文件,输出 Hello pingye ,执行成功。

$ go run client.go
Hello pingye

服务注册到了哪里?

在启动服务端的时候从终端输出的信息可以看出,有一个名为 greeter 的服务注册到了 Registry

2020-03-27 11:28:20 Starting [service] greeter
2020-03-27 11:28:20 Server [grpc] Listening on [::]:63763
2020-03-27 11:28:20 Registry [mdns] Registering node: greeter-8afc1183-a159-4473-a567-c13b83d1d75c

Registry是go-micro的注册模块,作用是将服务注册到某个介质,以方便客户端使用。注册模块默认支持cache、consul、etcd、k8s、mdns、memory等多种介质,默认使用的是mdns。

var (
	DefaultRegistry = NewRegistry()

	// Not found error when GetService is called
	ErrNotFound = errors.New("service not found")
	// Watcher stopped error when watcher is stopped
	ErrWatcherStopped = errors.New("watcher stopped")
)

mdns主要用于在没有传统DNS服务器的情况下,在局域网中实现主机之间的发现与通讯,它遵从DNS协议。

Go语言组件示例开源库,欢迎star

https://github.com/EnochZg/golang-examples

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Search User Interfaces

Search User Interfaces

Marti A. Hearst / Cambridge University Press / 2009-9-21 / USD 59.00

搜索引擎的本质是帮助用户更快、更方便、更有效地查找与获取所需信息。在不断改进搜索算法和提升性能(以技术为中心)的同时,关注用户的信息需求、搜寻行为、界面设计与交互模式是以用户为中心的一条并行发展思路。创新的搜索界面及其配套的交互机制对一项搜索服务的成功来说是至关重要的。Marti Hearst教授带来的这本新作《Search User Interfaces》即是后一条思路的研究成果,将信息检索与人......一起来看看 《Search User Interfaces》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具