Dapr .netcore与go的方法调用 电脑版发表于:2021/9/6 22:01 ![](https://img.tnblog.net/arcimg/hb/896fd38e95b346f9a0d98c54b135bb94.jpg) >#Dapr .netcore与go的方法调用 [TOC] tn2>主要回顾一下dapr是如何调用方法的。这里是通过.netcore程序调用go程序中的方法。 本章代码目录:https://gitee.com/zuxiazijiahebo/daprlearning 大致流程如下: ![](https://img.tnblog.net/arcimg/hb/4ed95315f5bd42549424b021a2c0c7f0.png) 创建.netcore Web API应用 ------------ tn2>创建时勾选上Docker的支持。 ![](https://img.tnblog.net/arcimg/hb/a7efd025fdae48b2af7834e33a2f9104.png) tn2>接着添加Dapr.AspNetCore包。 ![](https://img.tnblog.net/arcimg/hb/c4fd2f125a1d44baaee0aff1a335c675.png) tn2>在Startup.cs中添加我们的Dapr客户端服务。 ```csharp services.AddDaprClient(); ``` tn2>接着我们直接修改`WeatherForecastController.cs`类中的方法,通过sdk与http不同的方式发送消息给指定的dapr应用。 ```csharp [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly ILogger<WeatherForecastController> _logger; private readonly DaprClient _daprclient; public WeatherForecastController( ILogger<WeatherForecastController> logger, DaprClient daprclient ) { _daprclient = daprclient; _logger = logger; } [HttpGet] public string[] Get(int id) { return new string[]{ "/sdk/{id}", "/http/{id}" }; } [HttpGet("/sdk/{id}")] public async Task<string> Getsdk(int id) { Console.WriteLine("sdk begin..."); // 调用服务 var data = new { id = id, message = "hello [SDK]" }; // 调用goapp的simple方法 // InvokeMethodAsync 方法参数: 应用id,应用的方法,数据 await _daprclient.InvokeMethodAsync<object>("goapp", "simple", data); // 输出发送的内容 string result = string.Format("send Data: {0}", data); Console.WriteLine(result); return result; } [HttpGet("/http/{id}")] public async Task<string> Gethttp(int id) { Console.WriteLine("http begin..."); var client = DaprClient.CreateInvokeHttpClient(appId: "goapp"); var data = new { id = id, message = "hello [http]" }; // http的方式 var response = await client.PostAsJsonAsync("/simple", data); string result = string.Format("send Data: {0}", data); Console.WriteLine(result); return result; } } ``` tn2>关于.netcore的Dockerfile ```csharp FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build WORKDIR /src COPY ["Client.csproj", "."] RUN dotnet restore "./Client.csproj" COPY . . WORKDIR "/src/." RUN dotnet build "Client.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Client.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Client.dll"] ``` 编写go应用程序 ------------ tn2>然后创建`go`目录来编写我们的go应用程序。 ![](https://img.tnblog.net/arcimg/hb/81e992eb208d461db7277f59c5175031.png) tn2>在`app.go`中主要提供一个`/simple`的方法,并将它接收到的内容输出并打印出来。 ```go package main import ( "encoding/json" "log" "io/ioutil" "net/http" "fmt" "github.com/gorilla/mux" ) func simplemethod(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") s, _ := ioutil.ReadAll(r.Body) fmt.Fprintln(w, "%s",string(s)) fmt.Println(fmt.Sprintf("%s%s", "From dotnet app, data: ", string(s))) json.NewEncoder(w).Encode("go have already processed!") } func main() { router := mux.NewRouter() router.HandleFunc("/simple", simplemethod).Methods("POST", "OPTIONS") log.Fatal(http.ListenAndServe(":6000", router)) } ``` tn2>Dockerfile如下: ```bash FROM golang:1.15-buster as builder WORKDIR /dir COPY app.go . RUN go get -d -v RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM debian:buster-slim WORKDIR /root/ COPY --from=builder /dir/app . CMD ["./app"] ``` tn2>大家闲麻烦可以直接`git clone https://gitee.com/zuxiazijiahebo/daprlearning.git` Dapr应用在Docker中的部署 ------------ tn2>没安装的可以参考这篇 <a target="_blank" href="https://www.tnblog.net/hb/article/details/6334">安装Dapr</a> 安装好后进行初始化 ```bash dapr init ``` >### 安装dotnetapp应用 ```bash cd daprlearning/Client/Client/ # 生成 dotnet build # 切换到生成好的目录下 cd ./bin/Debug/netcoreapp3.1 # dapr开启dotnetapp应用,应用端口5000,dapr边车端口3500 dapr run --app-id dotnetapp --app-port 5000 --dapr-http-port 3500 dotnet Client.dll ``` ![](https://img.tnblog.net/arcimg/hb/4e687babf1864d28b6d365b3486a60a7.png) >### 安装go应用 ```bash cd daprlearning/Client/Client/go # 安装 gorilla/mux package go get -u github.com/gorilla/mux # 生成 go 程序 go build app.go # dapr 启动go程序 dapr run --app-id goapp --app-port 6000 --dapr-http-port 3501 ./app ``` ![](https://img.tnblog.net/arcimg/hb/c1638c9b0dbf4f94ae3e7dd1907ee090.png) >### 测试 tn2>我们通过如下几次请求来测试应用程序的调用情况 ```bash # 查看dotnetapp应用的两个接口 curl http://127.0.0.1:5000/weatherforecast # 开始调用 curl http://127.0.0.1:5000/sdk/1 curl http://127.0.0.1:5000/http/2 # Dapr CLI的方式测试 dapr invoke --app-id goapp --method simple --data "{\"data\": { \"orderId\": \"42\" } }" ``` ![](https://img.tnblog.net/arcimg/hb/5073cf28a61c48a993a6ee70b1c29e95.png) tn2>我们可以通过查看go应用的运行记录查看调用情况。 ![](https://img.tnblog.net/arcimg/hb/22f89bd0b3bc4dc5865e2c8cc5e40b9a.png) tn2>接着我们到zipkin中查看更详细的调用情况 访问`http://localhost:9411` ![](https://img.tnblog.net/arcimg/hb/8b988d26966c4d7db8af465cfab00518.png) ![](https://img.tnblog.net/arcimg/hb/ba260d81e1bc42989db5d8d1d0f5d640.png) tn2>我们可以看到它是调用的都是该地址:`POST {dapr url}/v1.0/invoke/{app-id}/method/{method}` 下面是链路情况: ![](https://img.tnblog.net/arcimg/hb/cdbec27290734fdd9a1461f469b84f1a.png) Dapr应用在k8s中的部署 ------------ ```bash # 初始化 dapr init -k ``` tn2>所有的部署都在Deploy目录下,镜像我也为大家打包好了。所以可以直接切换到Deploy目录下按照如下方式进行部署。 >### 安装redis tn2>我这里redis部署得很简单大家搞集群的话也是可以的。 ```bash docker pull redis:latest docker run -itd --name redis-test -p 6379:6379 redis ``` tn2>查看`ifconfig`修改一下redis.yaml的host地址 >### 安装项目 ```bash kubectl apply -f . # 查看Pod状态 kubectl get pod -w ``` tn2>稍等几分钟就好。 ![](https://img.tnblog.net/arcimg/hb/c0911fb6074f4b948f5890039ab21442.png) tn2>进行端口代理,然后打开一个新的Session执行下面命令进行测试 ```bash kubectl port-forward --address 0.0.0.0 service/dotnetclient 8080:80 ``` ```bash curl http://127.0.0.1:8080/weatherforecast # 开始调用 curl http://127.0.0.1:8080/sdk/1 curl http://127.0.0.1:8080/http/2 ``` ![](https://img.tnblog.net/arcimg/hb/06d7121d1d954c3495ad637c57e2d1bd.png) tn2>没有输出的原因是因为镜像没有更新你们不会出现这种问题的。下面是go的日志记录情况: ![](https://img.tnblog.net/arcimg/hb/5b93b3882d174923a9d5ec9e759b3c50.png) tn2>待续...