一、目标
在2021-10-17 dubbogo 基础使用中,介绍了如何用go
写一个部署到zookeeper
的dubbo
服务,这次编写一个go
语言的dubbo
调用端。并且支持同时连接到多个zookeeper
,根据需要调用不同zk
上的同一个服务
开动
1、部署zk
docker run --name zk1 --restart always -d -p 2181:2181 zookeeper
docker run --name zk2 --restart always -d -p 2182:2181 zookeeper
这里我们部署两个zookeeper
,端口号分别是2181
和2182
2、运行服务
- 进入
cmd/server
目录,修改dubbo.yml
中的zk
端口为2181
,然后go run main.go
启动服务1
- 进入
cmd/server
目录,修改dubbo.yml
中的zk
端口为2182
,然后go run main.go
启动服务2
3、客户端配置
-
dubbo.registries
配置两个
registries:
zk1:
protocol: zookeeper
timeout: 3s
address: 192.168.96.129:2181
zk2:
protocol: zookeeper
timeout: 3s
address: 192.168.96.129:2182
-
dubbo.consumer
按照如下配置
consumer:
request-timeout: 10s
check: false
references:
UserServiceEnv1:
retries: 0
registry-ids:
- zk1
protocol: dubbo
interface: com.demo.exp.service.UserService
UserServiceEnv2:
retries: 0
registry-ids:
- zk2
protocol: dubbo
interface: com.demo.exp.service.UserService
这里我们配置了两个UserService
的引用,并且设置了不同的别名。指定了每个引用连接各自的zk
.
4、客户端初始化
- 这里我们分别为要连接的不同
zk
定义结构体和对象,与【3】小节中配置文件定义的引用别名一致
var(
UsZk1 = &UserServiceEnv1{}
UsZk2 = &UserServiceEnv2{}
)
func InitUserServiceClient(){
dto.RegisterDtos(func(pojos ...dto.POJO){
for _,p := range pojos{
hessian.RegisterPOJO(p)
}
})
config.SetConsumerService(UsZk1)
config.SetConsumerService(UsZk2)
}
type UserServiceEnv1 struct {
service.UserService
}
type UserServiceEnv2 struct {
service.UserService
}
func(a *UserServiceEnv1)Reference()string{
return "UserServiceEnv1"
}
func(a *UserServiceEnv2)Reference()string{
return "UserServiceEnv2"
}
注意,这里service.UserService
为服务提供方的接口,我们直接继承他
- 服务提供方的
dto
定义
type POJO interface {
JavaClassName() string
}
type WithDto func(...POJO)
func RegisterDtos(registerFunc WithDto){
registerFunc(
&UserRequest{},
&UserResponse{},
)
}
const JavaDtoPgkName = "com.demo.exp.dto."
type UserRequest struct {
UserName string // 用户名
UserId string // 用户id
}
func(req UserRequest) JavaClassName() string{
return JavaDtoPgkName + "QueryUserParam"
}
type UserResponse struct {
UserName string // 用户名
UserId string // 用户id
BirthDate string // 出生日期
Age int64 // 年龄
IsDead bool // 是否已去世
}
func(req UserResponse) JavaClassName() string{
return JavaDtoPgkName + "QueryUserResponse"
}
- 服务提供方的
service
定义
//
// UserService
// @Description: 服务接口定义
//
type UserService struct {
QueryUser func(ctx context.Context, in *dto.UserRequest)(*dto.UserResponse, error)
}
func(a *UserService) Reference()string{
return "com.demo.exp.service.UserService"
}
5、调用代码
main.go
func main(){
clients.InitUserServiceClient()
err := config.Load(config.WithPath("./conf/dubbo.yml"))
if err != nil{
panic(err)
}
req := &dto.UserRequest{
UserName: "你好",
UserId: "123",
}
ctx, traceId := util.GetDubboContextWithAppName("dubbo-consumer")
//time.Sleep(10 * time.Second)
rsp, err := clients.UsZk1.QueryUser(ctx, req)
if err != nil{
logrus.WithFields(logrus.Fields{
"traceId": traceId,
"rsp": rsp,
"err": err,
}).Error("query zk1 userservice response")
}else{
logrus.WithFields(logrus.Fields{
"traceId": traceId,
"rsp": rsp,
}).Info("query zk1 userservice response")
}
req.UserId = "123456789"
ctx, traceId = util.GetDubboContextWithAppName("dubbo-consumer")
rsp, err = clients.UsZk2.QueryUser(ctx, req)
if err != nil{
logrus.WithFields(logrus.Fields{
"traceId": traceId,
"rsp": rsp,
"err": err,
}).Error("query zk2 userservice response")
}else{
logrus.WithFields(logrus.Fields{
"traceId": traceId,
"rsp": rsp,
}).Info("query zk2 userservice response")
}
select {
}
}
- 运行客户端
日志如下:
time="2022-04-03T17:20:01+08:00" level=error msg="query zk1 userservice response" err="no user found with id[123]" rsp="&{ 0 false}" traceId=e166fc1a
time="2022-04-03T17:20:01+08:00" level=info msg="query zk2 userservice response" rsp="&{dubbo-user1 123456789 1967-01-22 17:20:01 56 true}" traceId=998b5c6b
服务1
的日志如下:
time="2022-04-03T17:20:01+08:00" level=info msg="user_service:queryuser received call" appName=dubbo-consumer req="&{你好 123}" traceId=e166fc1a
服务2
的日志如下:
time="2022-04-03T17:20:01+08:00" level=info msg="user_service:queryuser received call" appName=dubbo-consumer req="&{你好 123456789}" traceId=998b5c6b
6、项目代码
github-dubbogodemo