go-micro v3 rpc服务一次改造经历
地址:https://github.com/go-micro/go-micro
grpc-test-demo:https://gitee.com/jn-shao/go-gmicro-rpc-test.git
go-micro api网关:
api网关替换为kong ,使用consul做dns服务器。
旧项目用的是http->go-micro v3 rpc,后端全都是自己的rpc,proto定义数据格式如下:
message Request {
string method = 1;
string path = 2;
map<string, Pair> header = 3;
map<string, Pair> get = 4;
map<string, Pair> post = 5;
string body = 6;
string url = 7;
}
message Response {
int32 statusCode = 1;
map<string, Pair> header = 2;
string body = 3;
}
不通用,非restful,参数动态前后端参数处理很麻烦,后续换网关,调整服务都很被动,go-micro v3不熟悉,发现go-micro v3 将server和client抽象出来有各自的管道处理(middleware),所以链路、熔断限流这些中间件使用框架本身封装的不需要动,只需使用插件替换server和client,改造难度不是很大,索性研究下全部替换掉。
注:服务名不能使用 . 不然dns会解析不到ip,可以通过下面命令测试自己的服务:
$ dig @<consul ip> -p 8600 <服务名>.service.consul SRV
api:
server转为http restful 替换为gin路由器:https://github.com/go-micro/plugins/tree/main/v3/server/http
官方例子可以看出插件是把路由器放进去,可以直接替换gin,简单来讲http基础包封装的http框架即实现Handler的ServeHTTP方法的都可以替换
client转为grpc client:https://github.com/go-micro/plugins/tree/main/v3/client/grpc
部分修改代码:
package initialize
func Routers() *gin.Engine {
Router := gin.Default()
ApiGroup := Router.Group("/v1")
router.InitPodRouter(ApiGroup)
return Router
}
package main
......
srv := httpServer.NewServer(
func(options *server.Options) {
options.Advertise = serviceHost + ":" + servicePort
},
server.Name("podApi"),
server.Version("latest"),
)
mux := initialize.Routers()
if err := srv.Handle(srv.NewHandler(mux)); err != nil {
common.Fatal(err)
}
service := micro.NewService(
//开启gin http server
micro.Server(srv),
//使用grpc client
micro.Client(grpcClient.NewClient(client.RequestTimeout(time.Second*5))),
......
)
......
global.PodService = go_micro_service_pod.NewPodService("podSrv", service.Client())
......
srv:
server转为grpc server:https://github.com/go-micro/plugins/tree/main/v3/server/grpc
部分修改代码:
package main
......
service := micro.NewService(
//开启grpc server
micro.Server(grpcServer.NewServer(func(options *server.Options) {
options.Advertise = global.ServerConfig.Host + ":" +
strconv.FormatUint(global.ServerConfig.Port, 10)
})),
......
)
配置中心consul:
旧项目注册中心和配置中心使用的都是consul,这里配置中心替换为nacos,使用go-micro v3封装的config:https://github.com/go-micro/plugins/tree/main/v3/config/source
viper:https://github.com/spf13/viper
nacos-sdk-go:https://github.com/nacos-group/nacos-sdk-go
部分修改代码:
package initialize
var configFileName = "config.yaml"
func InitConfig() {
var nacosConfig localconfig.NacosConfig
if err := GetLocalConfig(configFileName, &nacosConfig); err != nil {
common.Fatal(err)
}
config, err := GetNacosConfig(nacosConfig.Host, nacosConfig.Port, nacosConfig.Namespace,
nacosConfig.DataId, nacosConfig.Group)
if err != nil {
common.Fatal(err)
}
if err := config.Get().Scan(&global.ServerConfig); err != nil {
common.Fatal(err)
}
}
func GetLocalConfig(localConfigFileName string, config interface{}) error {
v := viper.New()
v.SetConfigFile(localConfigFileName)
if err := v.ReadInConfig(); err != nil {
return err
}
if err := v.Unmarshal(config); err != nil {
return err
}
fmt.Printf("本地配置信息:%+v", config)
zap.S().Infof("本地配置信息:%+v", config)
// 动态监控
func() {
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Printf("本地配置文件产生变化:%s", e.Name)
zap.S().Infof("本地配置文件产生变化:%s", e.Name)
_ = v.ReadInConfig() // 读取配置数据
_ = v.Unmarshal(config)
fmt.Printf("本地配置信息:%+v", config)
zap.S().Infof("本地配置信息:%+v", config)
})
}()
return nil
}
func GetNacosConfig(host string, port uint64, namespace string, dataId string, group string) (config.Config, error)
clientConfig := constant.ClientConfig{
NamespaceId: namespace,
TimeoutMs: 5000,
NotLoadCacheAtStart: true,
LogDir: "tmp/nacos/log",
CacheDir: "tmp/nacos/cache",
LogLevel: "debug",
}
nacosSource := nacos.NewSource(
nacos.WithAddress([]string{host + ":" + strconv.FormatUint(port, 10)}),
nacos.WithClientConfig(clientConfig),
nacos.WithDataId(dataId),
nacos.WithGroup(group),
)
conf, err := config.NewConfig()
if err != nil {
return conf, err
}
err = conf.Load(nacosSource)
return conf, err
}
注·:
(1)clientConfig中的LogDir和CacheDir要手动创建
(2)此处有一个坑,遇到nacos v1和v2兼容性问题,v2多开了一个9848 grpc端口,nacos-sdk-go v2配置http无效,都会转成grpc请求9848端口获取配置信息,当然使用nacos-sdk-go v1请求8848是没问题的,但go-micro v3 插件依赖的是nacos-sdk-go v2,前期没注意按照v1部署,需打开9848端口。被这个bug:https://github.com/nacos-group/nacos-sdk-go/issues/531干扰了,官方应该是有意将9848专门负责拉取配置信息,并且兼容v1版本
nacos-docker:https://github.com/nacos-group/nacos-docker
// 获取容器ip
$ docker image inspect --format='{{json .NetworkSettings.IPAddress}}' <nacos容器>
// 映射端口
$ iptables -t nat -A DOCKER -p tcp --dport 9848 -j DNAT --to-destination <nacos ip>:9848
go-micro v3 rpc服务一次改造经历的更多相关文章
- 为什么需要 RPC 服务?
链接:https://www.jianshu.com/p/362880b635f0 在传统的开发模式中,我们通常将系统的各个服务部署在单台机器,随着服务的扩展,这种方式已经完全无法满足系统大规模的扩展 ...
- 基于APM实现RPC服务和消息队列的指定消费
本文内容是基于公司现有框架整理的一篇专利文章.该框架包含完整的一套DevOps流程,包括工单系统(容器申请.服务部署等)\配置中心\路由配置中心\服务治理平台\消息治理平台\葛朗台(基于Docker+ ...
- go-micro开发RPC服务的方法及其运行原理
go-micro是一个知名的golang微服务框架,最新版本是v4,这篇文章将介绍go-micro v4开发RPC服务的方法及其运作原理. 基本概念 go-micro有几个重要的概念,后边开发RPC服 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<下篇>
基于netty轻量的高性能分布式RPC服务框架forest<上篇> 文章已经简单介绍了forest的快速入门,本文旨在介绍forest用户指南. 基本介绍 Forest是一套基于java开 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<上篇>
工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...
- Thrift 个人实战--Thrift RPC服务框架日志的优化
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
- Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
- 基于开源Dubbo分布式RPC服务框架的部署整合
一.前言 Dubbo 作为SOA服务化治理方案的核心框架,用于提高业务逻辑的复用.整合.集中管理,具有极高的可靠性(HA)和伸缩性,被应用于阿里巴巴各成员站点,同时在包括JD.当当在内的众多互联网项目 ...
- Metasploit RPC服务共享
1) 启动一个新的MSF RPC服务,-P参数后面指定连接到的RPC服务需要提供的口令,-U参数指定连接所需输入的用户名,使用-a 0.0.0.0将RPC服务绑定到所有的网络地址,否则服务默认只绑定到 ...
- RPC服务的发布订阅实现Thrift
Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务) 前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的 ...
随机推荐
- centos离线安装nvm
PS:因为项目需,客户现场不能联网需要不同的node版本来切换,里面已经内置好了node 8.11.2和12.1.0 两个版本,使用nvm可以切换 链接:https://pan.baidu.com/s ...
- 面试突击87:说一下 Spring 事务传播机制?
Spring 事务传播机制是指,包含多个事务的方法在相互调用时,事务是如何在这些方法间传播的. 既然是"事务传播",所以事务的数量应该在两个或两个以上,Spring 事务传播机制的 ...
- Spring boot定义多个配置文件并自由切换
在resource目录下定义三个配置文件 (properties文件已被我注销,配置文件建议用yml,如果properties文件与yml文件同时存在,SpringBoot会优选加载propertie ...
- 「国产系统」Tubian 0.3,兼容Windows和Android的GNU/Linux系统!
0.4版已发布:https://www.cnblogs.com/tubentubentu/p/16741197.html Sourceforge.net主页(提供下载):https://sourcef ...
- [题解] Codeforces 1268 D Invertation in Tournament 结论,兰道定理
题目 本题需要用到的结论: 一.兰道定理 二.如果\(n\geq4\),那么\(n\)个点的强连通竞赛图存在\(n-1\)个点的强连通子图. 证明: 现在有一个n-1个点的竞赛图(不一定强连通,称其为 ...
- [题解] Atcoder ABC 225 H Social Distance 2 生成函数,分治FFT
题目 首先还没有安排座位的\(m-k\)个人之间是有顺序的,所以先把答案乘上\((m-k)!\),就可以把这些人看作不可区分的. 已经确定的k个人把所有座位分成了k+1段.对于第i段,如果我们能求出这 ...
- DateSet的应用
一.知识描述 1.什么是DataSet? DataSet为一个数据集,可以看做是一个内存中的数据库,包括表.数据行.数据列以及表与表之间的关系. 创建一个DataSet后,它可以单独存在,不需要一直保 ...
- 2022.2.26A组总结&反思
今天的发挥比较奇妙.. T1:一眼dp+高斯消元,但是感觉细节比较多,然后先去做了T2,写完后回来推了一下就做出来了.比较裸,但是细节确实多,但是很可惜的一点是最后提交的代码没有判不合法,到手的100 ...
- get,post,put,delete四种基础方法对应增删改查
PUT,DELETE,POST,GET四种基础方法对应增删改查 1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数 ...
- Windows docker环境安装
前期准备 1.hyper-v功能 win10家庭版没有提供hyper-v的问题可通过如下脚本解决,保存为bat并运行重启电脑即可. pushd "%~dp0" dir /b %Sy ...