地址: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封装的confighttps://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

最新文章

  1. ABP 初探 之基于EasyUI的CURD
  2. 理解assign,copy,retain变strong
  3. 转:MPlayer源代码分析
  4. log4j 分类输出
  5. hdu 4038 Stone
  6. Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得
  7. sql 行转列 PIVOT 列转行 UNPIVOT
  8. spring-cloud-sleuth+zipkin源码探究
  9. Python_paramiko模块
  10. WPF设计界面不执行代码
  11. 接之前的文章,VS2017中使用Spring.NET配置以及使用方法(framework4.6.1超详细)
  12. 杭州富阳场口科目四考试公交路线(西溪北苑-&gt;场口)
  13. phpstrom2018
  14. Java 中的多线程你只要看这一篇就够了
  15. python——前端常用的标签
  16. ODT(old driver tree)详解(带例题)
  17. Chapter 4 需求工程
  18. CTF Writeup 一个专门收集WP的网站
  19. java动态代码的实现以及Class的卸载 (转至http://dustin.iteye.com/blog/46393)
  20. 205-react SyntheticEvent 事件

热门文章

  1. Git Review + Gerrit 安装及使用完成 Code-Review
  2. http和https分别是什么?
  3. IOC常用的创建对象方式
  4. 将Java代码打包成jar文件转换为.exe可执行程序方法
  5. PHP + ELK实现日志记录
  6. json文本数据
  7. C语言表白窗口程序
  8. 这才是使用ps命令的正确姿势
  9. Debian安装WPS的方法
  10. 使用 StringUtils.split 的坑