什么是dapr?为什么要使用它
官方文档https://docs.dapr.io/zh-hans/developing-applications/building-blocks/介绍dapr是一个分布式运行时Distributed Application Runtime是一个开源项目它把构建微服务的最佳实践沉淀为开发者可直接调用的标准化API让你能更专注于业务逻辑本身像下面这张图的介绍应用程序通过HTTP/gRPC通过dapr sdk与dapr运行时通信。这个dapr运行时是通过sidecar的方式部署到同应用的pod内的整体能力图谱● Building BlockDapr 对分布式应用开发过程中使用到的典型范式的抽象以及对应的 API 设计。通过这些抽象对客户侧可以规范 api 和使用方式而对实现侧则是可插拔可替换的基础。可以说这是整个 dapr 中最重要的一组概念。● Components对各个 building block 的具体实现。是 dapr 可扩展、可插拔的具体体现。● SDKDapr 提供给应用开发者使用的一组编程接口是对如何使用各 building block 的行为规范。也是 DAPR 实现多语言支持的具体表现。● Sidecar○ 首先这是一种应用部署模式将复杂的逻辑抽离到独立的程序中该程序与应用程序一起作为单独的进程或容器运行。这种部署模式我们称之为 Sidecar 模式。○ 其次特指这个运行在主程序旁边的独立进程我们称之为 Sidecar在 Dapr 语境下我们说的 运行时 就是 sidecar。Building Block下面只说一个简单理解下Service to Service Invocation服务调用使应用程序能够以 http 或 gRPC 的形式通过已知的端点相互通信。Dapr 提供了一个端点作为反向代理和内置服务发现的组合同提供内置的分布式跟踪和错误处理能力帮助应用开发。执行过程如下服务 A 以服务 B 为目标发起 HTTP 或 gRPC 调用该调用转到本地的 Dapr Sidecar。Dapr 使用在给定托管平台上运行的名称解析组件来发现服务B的位置。Dapr 将消息转发给服务B的Dapr Sidecar注意所有 Dapr Sidecar 之间的调用都将通过gRPC进行性能测试。只有服务和 Dapr Sidecar 之间的调用可以是HTTP 或 gRPC。服务 B 的 Dapr Sidecar 将请求转发到服务 B 上指定的端点或方法然后服务B运行其业务逻辑代码。服务 B 向服务 A 发送一个响应该响应到达服务 B 的 Sidecar。Dapr将响应转发给服务 A 的 Dapr Sidecar。服务A接收响应。使用下面是一个使用dapr sdk订阅metaq topic的例子importasyncioimportjsonimportloggingimportosfromtypingimportAny,Callable,Coroutineimportgrpcimporthttpxfromali_dapr_python.metaqimportMetaQClientfromapp.infrastructure.observability.telemetryimportget_tracerasyncdef_run_one_subscription_session(topic:str,consumer_group:str,tag:str,handler:Callable[[dict[str,Any]],Coroutine[Any,Any,None]],)-None:运行一次订阅会话建连 → 消费 → 流断退出。 抛出的异常由外层 _consume 的指数退避循环处理。 client_cmMetaQClient()clientawaitclient_cm.__aenter__()try:queueawaitclient.subscribe(topic,consumer_group,tagtag)logger.info(MetaQ subscribed: topic%s, group%s, tag%s,topic,consumer_group,tag,)whileTrue:messageawaitqueue.next_message()ifnotmessage:continuelogger.info(MetaQ message received: topic%s, message%s,topic,message.data())with_tracer.start_as_current_span(metaq.consume,attributes{metaq.topic:topic,metaq.tag:tag},):raw_datamessage.data()parsedjson.loads(raw_data)ifisinstance(raw_data,str)elseraw_dataawaithandler(parsed)awaitqueue.respond_success(message)logger.debug(MetaQ consumed: topic%s, message%s,topic,parsed)finally:try:awaitclient_cm.__aexit__(None,None,None)exceptException:# noqa: BLE001pass