Dapr Golang HTTP 调用

版本介绍

  • Go 版本:1.15
  • Dapr Go SKD 版本:0.11.1

工程结构

从上图可知,新建 3 个 Go 启动项目,cmd 为启动项目目录,其中 client/a/main.go 为客户端,用于调用服务。service/http/b、service/http/c 为服务项目。调用路径如下图所示。

graph LR;
go-client-a--1-->go-service-b;
go-service-b--2-->go-service-c;
go-service-c--3-->go-service-b;
go-service-b--4-->go-client-a;
  1. go-client-a 作为客户端调用服务 go-service-b;
  2. go-service-b 作为服务中转,既收来自 go-client-a 客户端的请求,又发起对 go-service-c 的调用;
  3. go-service-c 响应 go-service-b 的请求;
  4. go-service-b 响应 go-client-a 的请求。

internal

response.go 文件,封装返回数据。数据结构如下:

package internal

import (
"encoding/json"
"log"
) type HttpResult struct {
Message string
} func (r *HttpResult) ToBytes() (bytes []byte) {
var err error
bytes, err = json.Marshal(r)
if err != nil {
log.Fatal("数据转换失败")
}
return
}

go-service-c

go-service-c 做为调用链路末端,只需要提供监听端口,以及绑定路由。下面方法通过 s.AddServiceInvocationHandler("/hello", helloHandler) 方法绑定路由和处理方法。以下为 go-service-c 源码。

package main

import (
"context"
"errors"
"github.com/Zhang-Byte/dapr-golang/internal"
"github.com/dapr/go-sdk/service/common"
daprd "github.com/dapr/go-sdk/service/http"
"log"
"net/http"
) func main() {
s := daprd.NewService(":9003")
if err := s.AddServiceInvocationHandler("/hello", helloHandler); err != nil {
log.Fatalf("error adding invocation handler: %v", err)
} if err := s.Start(); err != nil && err != http.ErrServerClosed {
log.Fatalf("error listenning: %v", err)
}
} func helloHandler(_ context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
if in == nil {
err = errors.New("invocation parameter required")
return
}
log.Printf("The go-service-c service method hello has been invoked,recieve message is %v", string(in.Data))
httpResult := internal.HttpResult{Message: "This message is from Service C."}
out = &common.Content{
Data: httpResult.ToBytes(),
ContentType: in.ContentType,
DataTypeURL: in.DataTypeURL,
}
return
}

启动命令:

dapr run --app-id go-service-c \
--app-protocol http \
--app-port 9003 \
--dapr-http-port 3501 \
--log-level debug \
--components-path ./config \
go run ./cmd/service/http/c/main.go

go-service-b

go-service-b 相较于 go-service-c 的代码来说,添加了初始化客户端并发送请求的内容。查看代码 invokeService() 每次都会调用 client(),在 client() 中方法看上去每次都会新建一个客户端,查看 dapr 源码注释可知(Note, this default factory function creates Dapr client only once. All subsequent invocations will return the already created instance. ) 每次只会返回已经创建好的实例,因此使用完以后不必关闭此客户端。

package main

import (
"context"
"encoding/json"
"errors"
"github.com/Zhang-Byte/dapr-golang/internal"
dapr "github.com/dapr/go-sdk/client"
"github.com/dapr/go-sdk/service/common"
"log"
"net/http"
)
import daprd "github.com/dapr/go-sdk/service/http" func main() {
s := daprd.NewService(":9002")
if err := s.AddServiceInvocationHandler("/hello", helloHandler); err != nil {
log.Fatalf("error adding invocation handler: %v", err)
} if err := s.Start(); err != nil && err != http.ErrServerClosed {
log.Fatalf("error listenning: %v", err)
}
} func helloHandler(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
if in == nil {
err = errors.New("invocation parameter required")
return
}
log.Printf("The go-service-b service method hello has been invoked,recieve message is %v", string(in.Data)) msg := invokeService(ctx)
httpResult := internal.HttpResult{Message: msg} out = &common.Content{
Data: httpResult.ToBytes(),
ContentType: in.ContentType,
DataTypeURL: in.DataTypeURL,
}
return
} func invokeService(ctx context.Context) (msg string) {
client := client()
content := &dapr.DataContent{
ContentType: "text/plain",
Data: []byte("This is golang Service B."),
}
resp, err := client.InvokeServiceWithContent(ctx, "go-service-c", "hello", content)
if err != nil {
panic(err)
}
var result internal.HttpResult
if err := json.Unmarshal(resp, &result); err != nil {
log.Printf(err.Error())
}
msg = result.Message
return
} func client() dapr.Client {
client, err := dapr.NewClient()
if err != nil {
panic(err)
}
return client
}

启动命令:

dapr run --app-id go-service-b \
--app-protocol http \
--app-port 9002 \
--dapr-http-port 3500 \
--log-level debug \
--components-path ./config \
go run ./cmd/service/http/b/main.go

go-client-a

最后创建客户端,客户端每间隔 5 秒发起一次请求到 go-service-b 。

package main

import (
"context"
dapr "github.com/dapr/go-sdk/client"
"log"
"time"
) func main() {
ctx := context.Background() // create the client
client, err := dapr.NewClient()
if err != nil {
panic(err)
}
defer client.Close() content := &dapr.DataContent{
ContentType: "text/plain",
Data: []byte("This is client A."),
}
for {
resp, err := client.InvokeServiceWithContent(ctx, "go-service-b", "hello", content)
if err != nil {
panic(err)
}
log.Printf("go-service-b method hello has invoked, response: %s", string(resp)) time.Sleep(time.Second * 5)
} }

启动命令:

dapr run --app-id go-client-a \
--components-path ./config \
--log-level debug \
go run ./cmd/client/a/main.go

总结

client 启动后,得到返回值

== APP == 2020/11/06 11:26:41 go-service-b method hello has invoked, response: {"Message":"This message is from Service C."}

go-service-b 打印内容为:

== APP == 2020/11/06 11:31:51 The go-service-b service has been invoked,recieve message is This is client A.

go-service-c 打印内容为:

== APP == 2020/11/06 11:33:31 The go-service-c service method hello has been invoked,recieve message is This is golang Service B.

在命令行界面中输入 dapr dashboard 得到输出 Dapr Dashboard running on http://localhost:8080,访问 http://localhost:8080

源码地址:https://github.com/ZhangX-Byte/dapr-golang

Dapr Golang HTTP 调用的更多相关文章

  1. Dapr Java Http 调用

    版本介绍 Java 版本:8 Dapr Java SKD 版本:0.9.2 Dapr Java-SDK HTTP 调用文档 有个先决条件,内容如下: Dapr and Dapr CLI. Java J ...

  2. Dapr DotNet5 HTTP 调用

    Dapr DotNet5 HTTP 调用 版本介绍 Dotnet 版本:5.0.100 Dapr dotnet 版本:0.12.0-preview01 注意: Asp.Net Core 项目中的 la ...

  3. 手把手教你学Dapr - 4. 服务调用

    上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...

  4. [Golang] cgo 调用 .so 捕获异常问题

    最近需要在 go 中去调用 .so 库去完成一些事情,go 方面,利用 cgo 可以顺利的调用 .so 中的方法,但是有个问题是 go 没法捕获 .so 那边出现的异常.如果 .so 那边异常了,那么 ...

  5. golang动态调用方法

    package main import ( "fmt" "reflect" ) type YourT1 struct { } func (y *YourT1) ...

  6. C/C++调用Golang 二

    C/C++调用Golang 二 <C/C++调用Golang 一>简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用.本文总结具体项目中的使用场景,将介绍三种较复杂的 ...

  7. golang 查看代码调用关系图

    go-callvis 是github上一个开源项目,可以用来查看golang代码调用关系. 安装 安装graphviz $ brew install graphviz 安装go-callvis go ...

  8. Dapr 运用之集成 Asp.Net Core Grpc 调用篇

    前置条件: <Dapr 运用> 改造 ProductService 以提供 gRPC 服务 从 NuGet 或程序包管理控制台安装 gRPC 服务必须的包 Grpc.AspNetCore ...

  9. Golang调用Dll案例

    Golang调用Dll案例 前言 在家办公已经两个多星期了,目前最大的困难就是网络很差.独自一个人用golang开发调用dll的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依 ...

随机推荐

  1. SpringBoot整合SpringDataJPA,今天没啥事情就看了一下springboot整合springdataJPA,实在是香啊,SQL语句都不用写了

    SpringBoot整合SpringDataJPA 1.JPA概念 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映 ...

  2. Espruino似乎和Arduino一样

    参考:https://baike.baidu.com/item/Espruino Espruino 编辑 锁定 讨论   Espruino 是一个微处理器的 JavaScript 解释器,我们用它来创 ...

  3. Camera插件之CinematicCamera介绍

    Camera插件之CinematicCamera 继承自PerspectiveCame 构造函数引用的PerspectiveCamera的构造函数, 代码如下 var CinematicCamera ...

  4. 使用Appium进行iOS的真机自动化测试

    windows不支持appium连接ios,只适用于mac 使用Appium进行iOS的真机自动化测试 安装类库 Homebrew 如果没有安装过Homebrew,先安装[ homebrew ] np ...

  5. .NET Standard 简介

    系列目录     [已更新最新开发文章,点击查看详细] .NET Standard 是一套正式的 .NET API 规范,有望在所有 .NET 实现中推出. 推出 .NET Standard 的背后动 ...

  6. Docker开启远程连接,本地IDEA使用docker插件连接(不认证的版本和认证的版本都有)

    前言 在学校学习的时候,要部署一个Java程序,一般是打成war包,放到服务器上的tomcat的webapp里面去: 后来SpringBoot出现内置了tomcat,就直接打成jar包,丢到服务器任何 ...

  7. Makefile常用函数(转)

    一.字符串处理函数 1.$(subst FROM,TO,TEXT) 函数名称:字符串替换函数-subst. 函数功能:把字串"TEXT"中的"FROM"字符替换 ...

  8. net core 微服务 快速开发框架 Viper 初体验2020-10-17

    1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...

  9. docker启动服务---------------kafka+zookeeper

    docker run -d --name zookeeper -p 2181:2181 wurstmeister/zookeeperdocker run -d --name kafka -p 9092 ...

  10. go 加锁

    package mainimport ( "fmt" "math/rand" "sync" "time")var tic ...