最新Centos7环境使用Dapr1.6实现.Net6微服务调用实战

11 篇文章 1 订阅

    Dapr(**D**istributed Application Runtime)是一个开源、可移植、事件驱动的运行时。它使开发人员能够轻松地构建运行在云平台和边缘的弹性而微服务化的应用程序,无论是无状态还是有状态。Dapr 让开发人员能够专注于编写业务逻辑,而不是解决分布式系统的挑战,从而显著提高生产力并减少开发时间。此外,Dapr 也降低了大部分中小型企业基于微服务架构构建现代云原生应用的准入门槛。

Dapr 的核心构建模块如下:

  • 服务调用: 弹性服务与服务之间(service-to-service)调用可以在远程服务上启用方法调用,包括重试,无论远程服务在受支持的托管环境中运行在何处。
  • 状态管理:通过对键 / 值对的状态管理,可以很容易编写长时间运行、高可用性的有状态服务,以及同一个应用中的无状态服务。状态存储是可插入的,并且可以包括 Azure Cosmos 或 Redis,以及组件路线图上的其他组件,如 AWS DynamoDB 等。
  • 在服务之间发布和订阅消息(Pub/Sub):使事件驱动的架构能够简化水平可扩展性,并使其具备故障恢复能力。
  • 事件驱动的资源绑定:资源绑定和触发器在事件驱动的架构上进一步构建,通过从任何外部资源(如数据库、队列、文件系统、blob 存储、webhooks 等)接收和发送事件,从而实现可扩展性和弹性。例如,你的代码可以由 Azure EventHub 服务上的消息触发,并将数据写入 Azure CosmosDB。
  • 虚拟角色:无状态和有状态对象的模式,通过方法和状态封装使并发变得简单。Dapr 在其虚拟角色(Virtual Actors)运行时提供了许多功能,包括并发、状态、角色激活 / 停用的生命周期管理以及用于唤醒角色的计时器和提醒。
  • 服务之间的分布式跟踪:使用 W3C 跟踪上下文(W3C Trace Context)标准,轻松诊断和观察生产中的服务间调用,并将事件推送到跟踪和监视系统。

今天我们简单使用Dapr完成一个微服务的调用过程。

一 环境准备

1.1、安装Docker(windows10 必须开启默认Hyper-v)

我们准备一台Centos7.6虚拟机,docker安装比较简单,请看我另一篇文章Centos7.6安装 Docker CE

1.2、安装.NET Core SDK6.0

# 添加受信源
rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
# 安装.NET 6 SDK
yum install dotnet-sdk-6.0

详细安装步骤请看我的博文 Centos7.6安装最新的DotNet6开发环境

1.3、安装Dapr

1.3.1首先下载包文件

我们去 Dapr-CLI这个地址下载Dapr,目前最新版本是Dapr CLI v1.6.0,注意选择linux下amd64位的

wget -c https://github.com/dapr/cli/releases/download/v1.6.0/dapr_linux_amd64.tar.gz

 1.3.2下载后解压

这里我们解压到 /usr/local/bin目录

tar xf /export/server/dapr_linux_amd64.tar.gz -C /usr/local/bin

解压前,只有一个sqlite3

 解压后如下,注意dapr的执行权限,如果没有执行权限,需要添加 chmod x ./dapr

 解压后,我们直接执行dapr,如下说明安装好了

 1.3.3初始化Dapr

光安装好还不行,因为Dapr是基于Docker运行的,所以我们初始化一下Dapr

dapr init

 这里因为我没有翻墙软件,所以下载包会失败,我是重试了好几次成功的,如果报错,可以实行卸载命令,再重新初始化

dapr uninstall
dapr init

 检查初始化结果docker ps,有下面三个容器,证明dapr已经在运行了

 二 测试接口

2.1新建webapi项目

 这里建立2个api项目,一个学校api,一个专业api

 

 接下来我们在2个项目里,用NuGet包管理器都引入Dapr.AspNetCore

 我们测试的接口逻辑,是学校服务从专业服务调用专业列表数据

学校接口

 专业接口,模拟5条专业信息

 2.2 发布项目

发布前重要配置,我们在2个api项目的Program配置里增加把项目发布为Dapr识别的项目

builder.Services.AddControllers().AddDapr();

我们把2个api项目都发布

2.3 上传服务器

这里我用xftp,上传到dapr所在服务器

 2.4 运行major微服务

我们cd到major微服务的发布根目录major_publish下,执行

dapr run --app-id MajorService --app-port 9910 --dapr-http-port 19910 -- dotnet MajorMis.Api.dll --urls "http://*:9910"

 如下信息,证明启动成功了

[root@node2 bin]# cd /export/server/Net6/
You have new mail in /var/spool/mail/root
[root@node2 Net6]# ll
total 8
drwxr-xr-x 2 root root 4096 Mar  6 21:11 major_publish
drwxr-xr-x 2 root root 4096 Mar  6 21:12 school_publish
[root@node2 Net6]# cd major_publish/
[root@node2 major_publish]# dapr run --app-id MajorService --app-port 9910 --dapr-http-port 19910 -- dotnet MajorMis.Api.dll --urls "http://*:9910"
ℹ️  Starting Dapr with id MajorService. HTTP Port: 19910. gRPC Port: 40410
INFO[0003] starting Dapr Runtime -- version 1.6.0 -- commit 4bb25fab444c4f1a1bf0ffd74293dbd4fdcea580  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0003] log level set to: info                        app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0003] metrics server started on :44214/             app_id=MajorService instance=node2 scope=dapr.metrics type=log ver=1.6.0
INFO[0003] standalone mode configured                    app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0003] app id: MajorService                          app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0003] mTLS is disabled. Skipping certificate request and tls validation  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0004] local service entry announced: MajorService -> 192.168.88.101:43238  app_id=MajorService instance=node2 scope=dapr.contrib type=log ver=1.6.0
INFO[0004] Initialized name resolution to mdns           app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0004] loading components                            app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] component loaded. name: pubsub, type: pubsub.redis/v1  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] waiting for all outstanding components to be processed  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] detected actor state store: statestore        app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] component loaded. name: statestore, type: state.redis/v1  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] all outstanding components processed          app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] enabled gRPC tracing middleware               app_id=MajorService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0
INFO[0008] enabled gRPC metrics middleware               app_id=MajorService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0
INFO[0008] API gRPC server is running on port 40410      app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] enabled metrics http middleware               app_id=MajorService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0
INFO[0008] enabled tracing http middleware               app_id=MajorService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0
INFO[0008] http server is running on port 19910          app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] The request body size parameter is: 4         app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] enabled gRPC tracing middleware               app_id=MajorService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0
INFO[0008] enabled gRPC metrics middleware               app_id=MajorService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0
INFO[0008] internal gRPC server is running on port 43238  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0008] application protocol: http. waiting on port 9910.  This will block until the app is listening on that port.  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0010] application discovered on port 9910           app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
== APP == info: Microsoft.Hosting.Lifetime[14]
== APP ==       Now listening on: http://[::]:9910
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Application started. Press Ctrl+C to shut down.
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Hosting environment: Production
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Content root path: /export/server/Net6/major_publish/
INFO[0010] application configuration loaded              app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0010] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s  app_id=MajorService instance=node2 scope=dapr.runtime.actor type=log ver=1.6.0
INFO[0010] dapr initialized. Status: Running. Init Elapsed 7042.741769ms  app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0011] placement tables updated, version: 0          app_id=MajorService instance=node2 scope=dapr.runtime.actor.internal.placement type=log ver=1.6.0
ℹ️  Updating metadata for app command: dotnet MajorMis.Api.dll --urls http://*:9910
✅  You're up and running! Both Dapr and your app logs will appear here.

 我们访问浏览器,可以查到专业信息,这里有个坑注意:服务名(MajorService)区分大小写

http://192.168.88.101:19910/v1.0/invoke/MajorService/method/major

 接下来,我们启动学校微服务,来调用专业微服务的这个列表数据,新开一个shell终端,cd到学校服务发布目录school_publish,终端执行:

dapr run --app-id SchoolService --app-port 9920 --dapr-http-port 19920 -- dotnet SchoolMis.Api.dll --urls "http://*:9920"

 如下,看到输出You're up and running! Both Dapr and your app logs will appear here.则成功启动了

[root@node2 Net6]# cd school_publish/
[root@node2 school_publish]# dapr run --app-id SchoolService --app-port 9920 --dapr-http-port 19920 -- dotnet SchoolMis.Api.dll --urls "http://*:9920"
ℹ️  Starting Dapr with id SchoolService. HTTP Port: 19920. gRPC Port: 42086
INFO[0002] starting Dapr Runtime -- version 1.6.0 -- commit 4bb25fab444c4f1a1bf0ffd74293dbd4fdcea580  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] log level set to: info                        app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] metrics server started on :32846/             app_id=SchoolService instance=node2 scope=dapr.metrics type=log ver=1.6.0
INFO[0002] standalone mode configured                    app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] app id: SchoolService                         app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] mTLS is disabled. Skipping certificate request and tls validation  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] local service entry announced: SchoolService -> 192.168.88.101:37447  app_id=SchoolService instance=node2 scope=dapr.contrib type=log ver=1.6.0
INFO[0002] Initialized name resolution to mdns           app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] loading components                            app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] component loaded. name: pubsub, type: pubsub.redis/v1  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] waiting for all outstanding components to be processed  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] detected actor state store: statestore        app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] component loaded. name: statestore, type: state.redis/v1  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] all outstanding components processed          app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] enabled gRPC tracing middleware               app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0
INFO[0002] enabled gRPC metrics middleware               app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0
INFO[0002] API gRPC server is running on port 42086      app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] enabled metrics http middleware               app_id=SchoolService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0
INFO[0002] enabled tracing http middleware               app_id=SchoolService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0
INFO[0002] http server is running on port 19920          app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] The request body size parameter is: 4         app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] enabled gRPC tracing middleware               app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0
INFO[0002] enabled gRPC metrics middleware               app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0
INFO[0002] internal gRPC server is running on port 37447  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] application protocol: http. waiting on port 9920.  This will block until the app is listening on that port.  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0002] application discovered on port 9920           app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
== APP == info: Microsoft.Hosting.Lifetime[14]
== APP ==       Now listening on: http://[::]:9920
ℹ️  Updating metadata for app command: dotnet SchoolMis.Api.dll --urls http://*:9920
✅  You're up and running! Both Dapr and your app logs will appear here.

== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Application started. Press Ctrl+C to shut down.
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Hosting environment: Production
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Content root path: /export/server/Net6/school_publish/
INFO[0003] application configuration loaded              app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0003] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s  app_id=SchoolService instance=node2 scope=dapr.runtime.actor type=log ver=1.6.0
INFO[0003] dapr initialized. Status: Running. Init Elapsed 1296.726341ms  app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0
INFO[0003] placement tables updated, version: 0          app_id=SchoolService instance=node2 scope=dapr.runtime.actor.internal.placement type=log ver=1.6.0

接下来,用学校服务调用专业微服务,我们请求学校服务的默认get接口,可以看到返回的专业列表json数据

http://192.168.88.101:19910/v1.0/invoke/SchoolService/method/school

注意学校服务get请求的代码,我们是通过daprclient调用的专业微服务

        [HttpGet]
        public async Task<IEnumerable<MajorInfo>> Get()
        {
            _logger.LogInformation("[开始] 从专业微服务查询专业信息");
            // 远程调用商品微服务获取所有Sku信息
            var majors = await _daprClient.InvokeMethodAsync<IEnumerable<MajorInfo>>
                (HttpMethod.Get, "MajorService", "Major");

            _logger.LogInformation($"[结束] 从专业微服务查询的信息为: {majors.ToArray()?.ToString()}");

            return majors;
        }

 日志也能够证明

学校微服务日志打印如下

 专业微服务日志打印如下

 我们再执行命令dapr list,查看下dapr下运行的服务,可以看到2个微服务的信息

     我们再访问Dapr启动的时候自带的Zipkin链路追踪 http://192.168.88.101:9411/,可以看到调用情况

查看服务依赖关系

 

 今天的实战就到这里了,需要源码的朋友请关注我的公众号,后台回复【Dapr】,即可获取。

 总结
        感谢能看到这里的朋友😉

        本次的分享就到这里,猫头鹰数据致力于为大家分享技术干货😎

        如果以上过程中出现了任何的纰漏错误,烦请大佬们指正😅

        受益的朋友或对技术感兴趣的伙伴记得点赞关注支持一波🙏

        也可以扫描二维码或搜索关注我的微信公众号【猫头鹰数据分析】,留言交流🙏

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

终极量化数据

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值