go微服务系列(四) - http api中引入protobuf
1. protobuf相关依赖安装
- 第一步:下载grpc通用编译器
 
如下图,解压出来因平台而异会是一个protoc或者protoc.exe

- 第二步:把下载的二进制文件路径添加到环境变量中(为了能全局访问protoc)
- 这里以为mac为例子
 
 
# 打开这个
vim /etc/paths 
# 把路径添加进去
/Users/emm/others/protoc-3.12.4-osx-x86_64/bin/protoc
# 刷新环境变量
source /etc/paths
- 第三步: 安装go专用的protoc的生成器
 
go get github.com/golang/protobuf/protoc-gen-go
安装后会在GOPATH目录下生成可执行文件,protobuf的编译器插件protoc-gen-go,等下执行protoc命令会自动调用这个插件
- 第四步: 安装go-micro对应的插件
 
go get github.com/micro/protoc-gen-micro
2. 改造之前的client
2.1 新建proto文件
- 新建
models/protos文件夹 - 在上述文件夹下新建
prod.proto文件,内容如下: 
syntax = "proto3";
package Models;
message ProdModel {
  int32 Id = 1;
  string  Name = 2;
}
message ProdRequest {
  int32 Size = 1;
}
message ProdListResponse{
  repeated ProdModel data = 1;
}
2.2 运行protoc命令生成go文件
在models/protos文件夹下运行以下命令
protoc --micro_out=../ --go_out=../ prods.proto
2.3 然后把原来的map修改成具体的类型就可以了
package main
import (
	"context"
	"fmt"
	"gomicro-quickstart/goplugin_http_proto_invoker/models"
	"log"
	"github.com/micro/go-micro/client"
	"github.com/micro/go-micro/client/selector"
	"github.com/micro/go-micro/registry"
	"github.com/micro/go-plugins/client/http"
	"github.com/micro/go-plugins/registry/consul"
)
func main() {
	// 1. 注册consul地址
	cr := consul.NewRegistry(registry.Addrs("47.100.220.174:8500"))
	// 2. 实例化selector
	mySelector := selector.NewSelector(
		selector.Registry(cr),                     // 传入上面的consul
		selector.SetStrategy(selector.RoundRobin), // 指定获取实例的算法
	)
	// 3. 请求服务
	resp, err := callByGoPlugin(mySelector)
	if err != nil {
		log.Fatal("request API failed", err)
	}
	fmt.Printf("[服务调用结果]:\r\n %v", resp)
}
func callByGoPlugin(s selector.Selector) ([]*models.ProdModel, error) {
	// 1. 调用`go-plugins/client/http`包的函数获取它们提供的httpClient
	gopluginClient := http.NewClient(
		client.Selector(s),                     // 传入上面的selector
		client.ContentType("application/json"), // 指定contentType
	)
	// 2. 新建请求对象,传入: (1)服务名 (2)endpoint (3)请求参数
	req := gopluginClient.NewRequest("ProductService", "/v1/list",
		models.ProdRequest{Size: 2})
	// 3. 新建响应对象,并call请求,获取响应
	var resp models.ProdListResponse
	err := gopluginClient.Call(context.Background(), req, &resp)
	if err != nil {
		return nil, err
	}
	return resp.GetData(), nil
}
3. 处理json tag不一致的问题
如果服务端的model设置了json tag,如下

只有将客户端的proto文件生成的pb.go文件中的model的tag修改成一样的才可以
这里可以使用插件修改
第一步:下载插件
go get -u github.com/favadi/protoc-go-inject-tag
第二步,在proto文件上加注释
syntax = "proto3";
package models;
message ProdModel {
  // @inject_tag: json:"pid"
  int32 Id = 1;
  // @inject_tag: json:"pname"
  string  Name = 2;
}
message ProdRequest {
  int32 Size = 1;
}
message ProdListResponse{
  repeated ProdModel data = 1;
}
第三步:使用命令行批量修改
protoc-go-inject-tag -input=../prods.pb.go
												
											go微服务系列(四) - http api中引入protobuf的更多相关文章
- go微服务系列(四) - gRPC入门
		
1. 前言 2. gRPC与Protobuf简介 3. 安装 4. 中间文件演示 4.1 编写中间文件 4.2 运行protoc命令编译成go中间文件 5. 创建gRPC服务端 5.1 新建Produ ...
 - 【CHRIS RICHARDSON 微服务系列】微服务架构中的进程间通信-3
		
编者的话 |本文来自 Nginx 官方博客,是微服务系列文章的第三篇,在第一篇文章中介绍了微服务架构模式,与单体模式进行了比较,并且讨论了使用微服务架构的优缺点.第二篇描述了采用微服务架构的应用客户端 ...
 - 微服务系列(二):使用 API 网关构建微服务
		
编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨:微服务架构是如何影响客户端到服务端的通信,并提出一种使用 API 网关的方法. 作者介绍:Chris Richardso ...
 - 【微服务No.4】 API网关组件Ocelot+Consul
		
介绍: Ocelot是一个.NET API网关.该项目针对的是使用.NET运行微服务/面向服务架构的人员,他们需要一个统一的入口进入他们的系统.然而,它可以处理任何说HTTP并在ASP.NET Cor ...
 - 【CHRIS RICHARDSON 微服务系列】事件驱动的数据管理-5
		
编者的话 |本文来自 Nginx 官方博客,是「Chris Richardson 微服务」系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第三篇描述了微服务架构模 ...
 - Dubbo  微服务系列(03)服务注册
		
Dubbo 微服务系列(03)服务注册 [TOC] Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 图1 Dubbo经典架构图 注:本图来源 Dubbo官方架构 ...
 - 微服务系列(二)GRPC的介绍与安装
		
微服务系列(二)GRPC的介绍与安装 1.GPRC简介 GRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架.GRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多 ...
 - 微服务架构之「 API网关 」
		
在微服务架构的系列文章中,前面已经通过文章<架构设计之「服务注册 」>介绍过了服务注册的原理和应用,今天这篇文章我们来聊一聊「 API网关 」. 「 API网关 」是任何微服务架构的重要组 ...
 - Spring Cloud微服务系列文,服务调用框架Feign
		
之前博文的案例中,我们是通过RestTemplate来调用服务,而Feign框架则在此基础上做了一层封装,比如,可以通过注解等方式来绑定参数,或者以声明的方式来指定请求返回类型是JSON. 这种 ...
 
随机推荐
- Python元组索引、截取
			
Python元组索引.截取: 索引下标: tuple_1 = ('a','b','c','d','e','f','g','h') print(tuple_1[0]) # a print(tuple_1 ...
 - Python os.fchown() 方法
			
概述 os.fchown() 方法用于修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定.高佣联盟 www.cgewang.com Unix上可用. 语法 f ...
 - HTML <hr> 标签
			
高佣联盟 www.cgewang.com HTML <hr> 标签 实例 当内容的主题发生变化时,使用 <hr> 标签进行分隔: <h1>HTML</h1&g ...
 - 7.9 NOI模拟赛 C.走路 背包 dp 特异性
			
(啊啊啊 什么考试的时候突然降智这题目硬生生没想出来. 容易发现是先走到某个地方 然后再走回来的 然后在倒着走的路径上选择一些点使得最后的得到的最多. 设\(f_{i,j}\)表示到达i这个点选择的价 ...
 - 为什么switch不支持long
			
switch 支持的类型 在 Java 语言规范里中,有说明 switch 支持的类型有:char.byte.short.int.Character.Byte.Short.Integer.String ...
 - 快速构建一个springboot项目(一)
			
前言: springcloud是新一代的微服务框架而springboot作为springcloud的基础,很有必要对springboot深入学习一下. springboot能做什么? (1)spri ...
 - 使用javaScript 取cookie时需要注意的
			
function getCookie(name) { var cookies = window.top.document.cookie.split('; ');//分号后面有个空格 for (var ...
 - 《国际化Web项目测试:记第一次兼职测试的经历(一)》
			
疫情期间我一直在家远程办公,无意间接到了个做测试兼职的机会.在不耽搁本职工作的情况下,我从今年五月份开启了主职和副职的并行的状态.这种项目经历对于我来说算是一次全新的体验,当然也真是累的够呛.到目前为 ...
 - 【NOIP2017】跳房子 题解(单调队列优化线性DP)
			
前言:把鸽了1个月的博客补上 ----------------- 题目链接 题目大意:机器人的灵敏性为$d$.每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),m ...
 - Android 进度条(ProgressBar)和拖动条(Seekbar)补充“自定义组件”(总结)
			
这周结束了,我也码了一周的字,感觉还是很有种脚踏实地的感觉的,有时间就可以看看自己的总结再查漏补缺,一步一个脚印,做出自己最理想的项目. 今天我们讲两点: 1.ProgressBar: 其实前面也稍微 ...