背景

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

Go语言micro之快速搭建微服务的更多相关文章

  1. Spring-boot:快速搭建微服务框架

    前言: Spring Boot是为了简化Spring应用的创建.运行.调试.部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置. 简单来说,它提供了一堆依赖打包,并 ...

  2. 【译文】用Spring Cloud和Docker搭建微服务平台

    by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-mi ...

  3. Spring Cloud和Docker搭建微服务平台

    用Spring Cloud和Docker搭建微服务平台 This blog series will introduce you to some of the foundational concepts ...

  4. 十分钟搭建微服务框架(SpringBoot +Dubbo+Docker+Jenkins源码)

    本文将以原理+实战的方式,首先对“微服务”相关的概念进行知识点扫盲,然后开始手把手教你搭建这一整套的微服务系统. 这套微服务框架能干啥? 这套系统搭建完之后,那可就厉害了: 微服务架构 你的整个应用程 ...

  5. spring cloud+dotnet core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  6. spring cloud+.net core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  7. 【微服务】使用spring cloud搭建微服务框架,整理学习资料

    写在前面 使用spring cloud搭建微服务框架,是我最近最主要的工作之一,一开始我使用bubbo加zookeeper制作了一个基于dubbo的微服务框架,然后被架构师否了,架构师曰:此物过时.随 ...

  8. [手把手教你] 用Swoft 搭建微服务(TCP RPC)

    序言 Swoft Framework 基于 Swoole 原生协程的新时代 PHP 全栈式协程框架 Swoft 是什么? Swoft 框架是首个基于Swoole 原生协程的新时代 PHP高性能协程全栈 ...

  9. 通过GeneXus如何快速构建微服务架构

    概览 “微服务”是一个非常广泛的话题,在过去几年里,市面上存在着各种不同的定义. 虽然对这种架构方式没有一个非常精确的定义,但仍然有一些概念具有代表性. 微服务有着许多围绕业务能力.自动化部署.终端智 ...

随机推荐

  1. sublime安装vue插件

    1.打开sublime text 3按 Ctrl+Shift+P(相信你有单身的手速,同时按完这3个键) 2.选中上图中,框出来的内容,按下enter. 3.选择上图的第二个即:vue syntax ...

  2. marquee上下无缝滚动

    <!DOCTYPE html><html><head><meta charset="utf-8"><meta name=&qu ...

  3. tcpdump常用方法

    tcpdump -i eth0监视制定网络接口的数据包 tcpdump host 10.13.1.135监视所有10.13.1.135主机收到和发出的数据包 tcpdump src host 10.1 ...

  4. python爬虫之Appium手机APP爬虫

    一.Appium工作原理(详情见:https://www.cnblogs.com/sophia194910/p/7515165.html) Appium的功能其实很简单:监听一个端口,然后接收由cli ...

  5. datatable某列不排序、和自定义搜索、给数据里面加属性

    datatable中如果不想对前几列进行排序,使用以下代码: $('#informationList').DataTable({ //对0,1,2列不排序 "columnDefs" ...

  6. 得亏了它,我才把潜藏那么深的Bug挖出来

    2020年写了很多事故解决的文章,并不是我绞尽脑汁想出来的,而是真的遇到了这些问题.通过文章的方式记录下来,分享出去,才有意义. 事故背景 首先看下面的图吧,这是我从cat上截的图. 可以看到是一个R ...

  7. 有史以来最全的CMD命令

    说在前面的话: 本篇是博主通过网上查找整理而成的,且都是亲测可以的一些cmd命令,可以说是很齐全了,当然,如果有不可以运行的代码,欢迎大家留言指出,我会不断完善的,谢谢. CMD作用: 掌握一些基本的 ...

  8. Unity C# Scoket Thread

    关于 Scoket和Thread 也没什么要说的,网上有很多资料.但是需要注意的是 Scoket和Thread 都需要创建和杀死.不然一定会造成程序假死.好了上代码 服务器: using System ...

  9. git的日常使用(补课)

    使用git的一些反响 如果在github上做一个仓库来使用的话... 首先手动在github上创建一个空的仓库,默认没有任何东西的 使用git的命令 git pull 创建的github仓库地址 能把 ...

  10. django 从零开始 6 数据库模型增删改查

    这些都是凭记忆写下的,有些会漏掉,在之后的笔记中会写 和flask query不同,django是使用objects进行一个查询 查询 单条记录 django 模型.bojects.get(查询的字段 ...