Go语言micro之快速搭建微服务
背景
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之快速搭建微服务的更多相关文章
- Spring-boot:快速搭建微服务框架
前言: Spring Boot是为了简化Spring应用的创建.运行.调试.部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置. 简单来说,它提供了一堆依赖打包,并 ...
- 【译文】用Spring Cloud和Docker搭建微服务平台
by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-mi ...
- Spring Cloud和Docker搭建微服务平台
用Spring Cloud和Docker搭建微服务平台 This blog series will introduce you to some of the foundational concepts ...
- 十分钟搭建微服务框架(SpringBoot +Dubbo+Docker+Jenkins源码)
本文将以原理+实战的方式,首先对“微服务”相关的概念进行知识点扫盲,然后开始手把手教你搭建这一整套的微服务系统. 这套微服务框架能干啥? 这套系统搭建完之后,那可就厉害了: 微服务架构 你的整个应用程 ...
- spring cloud+dotnet core搭建微服务架构:服务发现(二)
前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...
- spring cloud+.net core搭建微服务架构:服务发现(二)
前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...
- 【微服务】使用spring cloud搭建微服务框架,整理学习资料
写在前面 使用spring cloud搭建微服务框架,是我最近最主要的工作之一,一开始我使用bubbo加zookeeper制作了一个基于dubbo的微服务框架,然后被架构师否了,架构师曰:此物过时.随 ...
- [手把手教你] 用Swoft 搭建微服务(TCP RPC)
序言 Swoft Framework 基于 Swoole 原生协程的新时代 PHP 全栈式协程框架 Swoft 是什么? Swoft 框架是首个基于Swoole 原生协程的新时代 PHP高性能协程全栈 ...
- 通过GeneXus如何快速构建微服务架构
概览 “微服务”是一个非常广泛的话题,在过去几年里,市面上存在着各种不同的定义. 虽然对这种架构方式没有一个非常精确的定义,但仍然有一些概念具有代表性. 微服务有着许多围绕业务能力.自动化部署.终端智 ...
随机推荐
- Redis list实现原理 - 双向循环链表
双向链表 双向表示每个节点知道自己的直接前驱和直接后继,每个节点需要三个域 查找方向可以是从左往右也可以是从右往左,但是要实现从右往左还需要终端节点的地址,所以通常会设计成双向的循环链表; 双向的循环 ...
- Ubuntu几秒钟没有任何操作自动黑屏
在鼠标或键盘30秒内没有做任何操作以后,显示器自动黑屏. 重新点击鼠标或键盘,屏幕唤醒. 设置中心各种设置方式都已经尝试过.无效. $xset -q // 执行该命令 Keyboard Control ...
- Python读取和写入文件
1 从文件中读取数据 1.1 读取整个文件 创建名为test的txt文本文件,添加内容如下所示: 123456789023456789013456789012 实现代码: with open('tes ...
- JZOJ 1775. 合并果子2 (Standard IO)
1775. 合并果子2 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 在一个果园里,多多已经将所有的果子 ...
- JZOJ 1492. 烤饼干
1492. 烤饼干 (Standard IO) Description NOIP烤饼干时两面都要烤,而且一次可以烤R(1<=R<=10)行C(1<=C<=10000)列个饼干, ...
- 内存:你跑慢点行不行?CPU:跑慢点你养我吗?内存:我不管!(内附超全思维导图)
主存(RAM) 是一件非常重要的资源,必须要认真对待内存.虽然目前大多数内存的增长速度要比 IBM 7094 要快的多,但是,程序大小的增长要比内存的增长还快很多.不管存储器有多大,程序大小的增长速度 ...
- php实现post跳转
大家否知道php可以利用header('Location')实现get请求跳转. php利用curl可以实现模拟post请求. 但是却找不到php现成的实现post跳转.那么问题来了,如果有这个需求该 ...
- 测试 - 某网站ACCESS数据库注入漏洞
元宵节 团团圆圆总少不了一篇文 测试是否有注入 测试数据库类型 后面不用注释猜到可能是access 验证一下 这里说一下MySQL和ACCESS以及MSSQL的判断语句 MySQL:and len ...
- django中CBV源码分析
前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式处理请求. CBV(class base views)是在视图里基于类的形式处理请求. ...
- 系统之眼!Linux系统性能监控工具Glances
一.Glances介绍 glances是一个基于python语言开发,可以为linux或者UNIX性能提供监视和分析性能数据的功能.glances在用户的终端上显示重要的系统信息,并动态的进行更新,让 ...