中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang基于泛化調用與Nacos實現Dubbo代理的方法是什么

發布時間:2023-04-04 14:32:32 來源:億速云 閱讀:231 作者:iii 欄目:開發技術

這篇“Golang基于泛化調用與Nacos實現Dubbo代理的方法是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Golang基于泛化調用與Nacos實現Dubbo代理的方法是什么”文章吧。

準備

由于是通用的 dubbo 代理,因此肯定需要使用泛化調用。而我們使用的注冊中心是 nacos,因此也需要使用 nacos-sdk 來獲取 provider 的實例信息。

實現

項目結構


├── dubbo/                 
│    ├─ generic.go   # 泛化調用 dubbo 接口
│    ├─ models.go    # 數據模型
│    └─ nacos.go     # 獲取 nacos 元信息
├── web/                       
│    └─ server.go    # 對外 http 接口

├── main.go          # main 入口函數
└── go.mod           # 模塊描述文件

go.mod

module dubbo-proxy

go 1.20

require (
	dubbo.apache.org/dubbo-go/v3 v3.0.5
	github.com/apache/dubbo-go-hessian2 v1.12.0
	github.com/gin-gonic/gin v1.9.0
	github.com/nacos-group/nacos-sdk-go/v2 v2.1.2
)

返回數據格式

dubbo/models.go:

type DataResult struct {
	Env     string `json:"env,omitempty"`  // 當前調用環境
	Code    string `json:"code,omitempty"` // 返回結果碼
	Data    any    `json:"data,omitempty"` // 返回結果
	Message string `json:"message,omitempty"` // 返回消息
}

獲取 nacos 元信息

根據環境創建 nacos client

func buildClient(env string, serverCfgs []constant.ServerConfig) naming_client.INamingClient {
	client, _ := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig: constant.NewClientConfig(
				constant.WithNamespaceId(env),
				constant.WithNotLoadCacheAtStart(true),
			),
			ServerConfigs: serverCfgs,
		},
	)
	return client
}

獲取服務實例

func SelectInstance(env, servName string) (string, bool) {
	cli, ok := cliMap[env]
	if !ok {
		return "client not found from " + env, false
	}
	instances, e := cli.SelectInstances(vo.SelectInstancesParam{
		ServiceName: fmt.Sprintf("providers:%s:1.0.0:", servName),
		HealthyOnly: true,
	})
	if e != nil {
		return "instance not found, " + e.Error(), false
	}
	if len(instances) <= 0 {
		return "instance not found", false
	}
	return fmt.Sprintf("dubbo://%s:%d", instances[0].Ip, instances[0].Port), true
}

完整代碼

dubbo/nacos.go:

package dubbo

import (
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
)

var cliMap = make(map[string]naming_client.INamingClient)

func init() {
	serverCfgs := []constant.ServerConfig{
		*constant.NewServerConfig("127.0.0.1", 6801, constant.WithContextPath("/nacos")),
	}
	cliMap["local"] = buildClient("local", serverCfgs)
	cliMap["dev"] = buildClient("develop", serverCfgs)
	cliMap["test"] = buildClient("test", serverCfgs)
}

func buildClient(env string, serverCfgs []constant.ServerConfig) naming_client.INamingClient {
	client, _ := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig: constant.NewClientConfig(
				constant.WithNamespaceId(env),
				constant.WithNotLoadCacheAtStart(true),
			),
			ServerConfigs: serverCfgs,
		},
	)
	return client
}

func SelectInstance(env, servName string) (string, bool) {
	cli, ok := cliMap[env]
	if !ok {
		return "client not found from " + env, false
	}
	instances, e := cli.SelectInstances(vo.SelectInstancesParam{
		ServiceName: fmt.Sprintf("providers:%s:1.0.0:", servName),
		HealthyOnly: true,
	})
	if e != nil {
		return "instance not found, " + e.Error(), false
	}
	if len(instances) <= 0 {
		return "instance not found", false
	}
	return fmt.Sprintf("dubbo://%s:%d", instances[0].Ip, instances[0].Port), true
}

泛化調用

dubbo root 配置

var dubboRoot = cfg.NewRootConfigBuilder().SetProtocols(map[string]*cfg.ProtocolConfig{
	dubbo.DUBBO: {
		Params: map[string]interface{}{
			"getty-session-param": map[string]interface{}{
				"max-msg-len": 1024000,
			},
		},
	},
}).Build()

泛化調用

func GenericInvoke(iName, method, env string, req []byte) DataResult {
	instance, ok := SelectInstance(env, iName)
	if !ok {
		return DataResult{
			Code:    "ERROR",
			Message: instance,
		}
	}
	cfg.Load(cfg.WithRootConfig(dubboRoot))
	refConf := cfg.ReferenceConfig{
		InterfaceName: iName,
		Cluster:       "failover",
		Protocol:      dubbo.DUBBO,
		Generic:       "true",
		Version:       "1.0.0",
		URL:           instance,
	}
	refConf.Init(dubboRoot)
	refConf.GenericLoad("dubbo-proxy")
	var args = utils.Unmarshal(req, &map[string]hessian.Object{})
	raw, err := refConf.GetRPCService().(*generic.GenericService).Invoke(context.Background(), method, nil, []hessian.Object{args})
	if err != nil {
		panic(err)
	}
	rawResult := raw.(map[interface{}]interface{})
	result := DataResult{
		Code:    rawResult["code"].(string),
		Message: rawResult["message"].(string),
		Data:    utils.ConvertAs(rawResult["data"], map[string]interface{}{}),
	}
	return result
}

注意25-30行要根據業務自身的返回數據格式包裝結果:

/*
	這個例子的 dubbo 調用都會返回通過的結構:
	{
		"code": "",
		"message": "",
		"data": // 真正的調用結果
	}
*/
rawResult := raw.(map[interface{}]interface{})
result := DataResult{
	Code:    rawResult["code"].(string),
	Message: rawResult["message"].(string),
	Data:    rawResult["data"],
}

完整代碼

dubbo/generic.go:

package dubbo

import (
	"context"
	"dubbo-proxy/utils"
	cfg "dubbo.apache.org/dubbo-go/v3/config"
	"dubbo.apache.org/dubbo-go/v3/config/generic"
	_ "dubbo.apache.org/dubbo-go/v3/imports"
	"dubbo.apache.org/dubbo-go/v3/protocol/dubbo"
	hessian "github.com/apache/dubbo-go-hessian2"
)

var dubboRoot = cfg.NewRootConfigBuilder().SetProtocols(map[string]*cfg.ProtocolConfig{
	dubbo.DUBBO: {
		Params: map[string]interface{}{
			"getty-session-param": map[string]interface{}{
				"max-msg-len": 1024000,
			},
		},
	},
}).Build()

func GenericInvoke(iName, method, env string, req []byte) DataResult {
	instance, ok := SelectInstance(env, iName)
	if !ok {
		return DataResult{
			Code:    "ERROR",
			Message: instance,
		}
	}
	cfg.Load(cfg.WithRootConfig(dubboRoot))
	refConf := cfg.ReferenceConfig{
		InterfaceName: iName,
		Cluster:       "failover",
		Protocol:      dubbo.DUBBO,
		Generic:       "true",
		Version:       "1.0.0",
		URL:           instance,
	}
	refConf.Init(dubboRoot)
	refConf.GenericLoad("dubbo-proxy")
	var args = utils.Unmarshal(req, &map[string]hessian.Object{})
	raw, err := refConf.GetRPCService().(*generic.GenericService).Invoke(context.Background(), method, nil, []hessian.Object{args})
	if err != nil {
		panic(err)
	}
	rawResult := raw.(map[interface{}]interface{})
	result := DataResult{
		Code:    rawResult["code"].(string),
		Message: rawResult["message"].(string),
		Data:    utils.ConvertAs(rawResult["data"], map[string]interface{}{}),
	}
	return result
}

提供 http 服務

dubbo/generic.go:

package web

import (
	"dubbo-proxy/dubbo"
	"github.com/gin-gonic/gin"
	"net/http"
)

func Run() {
	router := gin.Default()
	router.POST("/:intf/:method", func(c *gin.Context) {
		intf := c.Param("intf")
		method := c.Param("method")
		env := c.Query("env")
		data, err := c.GetRawData()
		if err != nil {
		    panic(err)
		}
		res := dubbo.GenericInvoke(intf, method, env, data)
		res.Env = env
		c.JSON(http.StatusOK, res)
	})
	panic(router.Run(":7788"))
}

啟動

main.go:

package main

import "dubbo-proxy/web"

func main() {
	web.Run()
}

效果

Golang基于泛化調用與Nacos實現Dubbo代理的方法是什么

以上就是關于“Golang基于泛化調用與Nacos實現Dubbo代理的方法是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

海南省| 贺兰县| 那曲县| 洛川县| 五大连池市| 铜鼓县| 辽宁省| 东乡族自治县| 滦南县| 海城市| 介休市| 荆州市| 林芝县| 永济市| 方山县| 东阿县| 谢通门县| 灵宝市| 河池市| 平武县| 大城县| 麻阳| 张掖市| 潞城市| 敦煌市| 称多县| 德格县| 隆回县| 嘉祥县| 安乡县| 南皮县| 巴塘县| 鄂尔多斯市| 望都县| 合川市| 山东省| 迁西县| 临邑县| 琼海市| 高雄县| 松江区|