最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【世界聚看点】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 header = 3;    map get = 4;    map post = 5;    string body = 6;    string url = 7;}message Response {    int32 statusCode = 1;    map header = 2;    string body = 3;}

不通用,非restful,参数动态前后端参数处理很麻烦,后续换网关,调整服务都很被动,go-micro v3不熟悉,发现go-micro v3 将server和client抽象出来有各自的管道处理(middleware),所以链路、熔断限流这些中间件使用框架本身封装的不需要动,只需使用插件替换server和client,改造难度不是很大,索性研究下全部替换掉。

注:服务名不能使用 . 不然dns会解析不到ip,可以通过下面命令测试自己的服务:

$ dig @ -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 servermicro.Server(srv),//使用grpc clientmicro.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 servermicro.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.NacosConfigif 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}}" // 映射端口$ iptables -t nat -A DOCKER -p tcp --dport 9848 -j DNAT --to-destination :9848

关键词: 配置文件 数据格式 可以看出