暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Dapr 究竟是如何工作

编程阁楼 2021-04-11
605
今天我们重点介绍几种常用的building block的实现机制。

1. Service-to-service invocation(服务调用)

Dapr addresses these challenges by providing a service invocation API that acts as a combination of a reverse proxy with built-in service discovery, while leveraging built-in distributed tracing, metrics, error handling, encryption and more.

Dapr uses a sidecar architecture. To invoke an application using Dapr, you use the invoke
API on any Dapr instance. The sidecar programming model encourages each applications to talk to its own instance of Dapr. The Dapr instances discover and communicate with one another.


提到跨服务方法调用,这个大家肯定会想,这简单啊,不就是服务暴露API就好了嘛。是,但不完全是。比如nodeapp暴露了一个API:http://10.0.0.2:8000/neworder
,按照传统的方式,直接HTTP POST这个API访问就得了,但在Dapr中,其提供了服务间方法调用的接口规范,需要按照POST/GET/PUT/DELETE http://localhost:<daprPort>/v1.0/invoke/<appId>/method/<method-name>
的格式进行访问。那假设pythonapp需要访问nodeapp的方法,就需要POST一个请求到http://localhost:3500/v1.0/invoke/nodeapp/method/neworder
。你可能会想为何多此一举呢?此举的意义何在呢?目的很简单,就是为了实现对服务间网络通信的控制以完成诸如服务发现、流量控制、重试熔断、安全访问等,而这相关的网络控制功能就是集成在Dapr的Sidecar中,以对应用透明的方式集成进来的。整体的服务调用流程如下图所示:


1. Service A makes an HTTP or gRPC call targeting Service B. The call goes to the local Dapr sidecar.
2. Dapr discovers Service B’s location using the name resolution component which is running on the given hosting platform.
3. Dapr forwards the message to Service B’s Dapr sidecar
Note: All calls between Dapr sidecars go over gRPC for performance. Only calls between services and Dapr sidecars can be either HTTP or gRPC
4. Service B’s Dapr sidecar forwards the request to the specified endpoint (or method) on Service B. Service B then runs its business logic code.
5. Service B sends a response to Service A. The response goes to Service B’s sidecar.
6. Dapr forwards the response to Service A’s Dapr sidecar.
7. Service A receives the response.

其中,服务发现机制:

Dapr can run on any hosting platform. For the supported hosting platforms this means they have a name resolution component developed for them that enables service discovery. For example, the Kubernetes name resolution component uses the Kubernetes DNS service to resolve the location of other applications running in the cluster. For local and multiple physical machines this uses the mDNS protocol.

2. state store(状态管理)

A state store in Dapr is described using a Component
file:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
namespace: default
spec:
type: state.<DATABASE>
version: v1
metadata:
- name: <KEY>
value: <VALUE>
- name: <KEY>
value: <VALUE>
...

当前已支持的state store类型如下:

  • AWS DynamoDB

  • Aerospike

  • Azure Blob Storage

  • Azure CosmosDB

  • Azure Table Storage

  • Cassandra

  • Cloud Firestore (Datastore mode)

  • CloudState

  • Couchbase

  • Etcd

  • HashiCorp Consul

  • Hazelcast

  • Memcached

  • MongoDB

  • PostgreSQL

  • Redis

  • RethinkDB

  • SQL Server

  • Zookeeper

更多细节参见: Supported state stores

在进行微服务开发时,绕不开的话题就是服务间的状态共享、并发一致性问题。对于状态共享,你可能会说,各个服务连接到同一个Redis实例就OK了。是,但不得不考虑潜在的更新冲突的问题。Dapr 以更友好的HTTP API的方进行状态的存储和读取,同时支持通过ETags进行并发控制,并支持通过选项设置并发和一致性行为。
  • 存储:POST http://localhost:<daprPort>/v1.0/state/<storename>
  • 读取:GET http://localhost:<daprPort>/v1.0/state/<storename>/<key>
  • 删除:DELETE http://localhost:<daprPort>/v1.0/state/<storename>/<key>
    以下是保存状态的举例:
    • concurrency
      用于指定并发选项:first-write-wins/last-write-wins(以第一次写入为准/以最后一次写入为准),默认以最后一次写入为准。
    • consistency
      用于指定一致性选项:strong/eventual(强一致性/最终一致性),默认为最终一致性。
curl -X POST http://localhost:3500/v1.0/state/starwars \
-H "Content-Type: application/json" \
-d '[
{
"key": "weapon",
"value": "DeathStar",
"etag": "xxxxx",
"options": {
"concurrency": "first-write",
"consistency": "strong"
}
}
]'

3. Pub/Sub(消息发布及订阅)

Dapr integrates with pub/sub message buses to provide applications with the ability to create event-driven, loosely coupled architectures where producers send events to consumers via topics.

发布订阅模式,主要是用于微服务间基于消息进行相互通信。你可能也会说,这也要拿出来说,我搞个RabbitMQ/RocketMQ就是了。是的,但我还是要说,Dapr提供了一致性的消息发布、订阅API,而无需关注具体使用的是何种Message Broker,从而和底层基础设施解耦。

  • 发布:POST http://localhost:<daprPort>/v1.0/publish/<pubsubname>/<topic>[?<metadata>]

  • 获取可订阅主题:GET http://localhost:<appPort>/dapr/subscribe

  • 订阅:POST http://localhost:<appPort>/<path>

Pub/Sub也可以跨多个namespace:

Supported pub/sub brokers

4. secret stores

Dapr integrates with secret stores to provide apps and other components with secure storage and access to secrets such as access keys and passwords. Each secret store component has a name and this name is used when accessing a secret.

配置格式:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: secretstore
namespace: default
spec:
type: secretstores.<NAME>
version: v1
metadata:
- name: <KEY>
value: <VALUE>
- name: <KEY>
value: <VALUE>
...
不同类型的secret stores
具有不同的特定配置项,如下配置的AWS secrets
:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: awssecretmanager
namespace: default
spec:
type: secretstores.aws.secretmanager
version: v1
metadata:
- name: region
value: "[aws_region]"
- name: accessKey
value: "[aws_access_key]"
- name: secretKey
value: "[aws_secret_key]"
- name: sessionToken
value: "[aws_session_token]"
Supported secret stores

5. bindings(资源绑定)

Using bindings, you can trigger your app with events coming in from external systems, or interface with external systems. This building block provides several benefits for you and your code:

  • Remove the complexities of connecting to, and polling from, messaging systems such as queues and message buses

  • Focus on business logic and not implementation details of how to interact with a system

  • Keep your code free from SDKs or libraries

  • Handle retries and failure recovery

  • Switch between bindings at run time

  • Build portable applications where environment-specific bindings are set-up and no code changes are required


Dapr通过建立触发器与资源的绑定,可以从任何外部源(例如数据库,队列,文件系统等)接收和发送事件,而无需借助消息队列,即可实现灵活的业务场景。Dapr的Bindings分为两种:
  • Input Bindings(输入绑定):当外部资源的事件发生时,借助输入绑定,你的应用即可通过特定的API: POST http://localhost:<appPort>/<name>
    收到外部资源的事件,用于处理特定逻辑。
  • Output Bindings(输出绑定):输出绑定允许你调用外部资源。比如,在订单处理场景中,在订单 创建成功后,可以将订单信息通过Dapr的绑定API: POST/PUT http://localhost: <daprPort>/v1.0/bindings/<name>
    输出到Kafka特定队列上。

一个binding配置样例:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: sample-topic
spec:
type: bindings.kafka
version: v1
metadata:
# Kafka broker connection setting
- name: brokers
value: [kafka broker address]
# consumer configuration: topic and consumer group
- name: topics
value: sample
- name: consumerGroup
value: group1
# publisher configuration: topic
- name: publishTopic
value: sample
- name: authRequired
value: "false

当前已支持的output binding components列表参见:bindings


6. Observability(可观测)

Dapr记录指标,日志,链路以调试和监视Dapr和用户应用的运行状况。Dapr支持分布式跟踪,其使用W3C跟踪上下文标准和开放式遥测技术,可以轻松地诊断在生产环境中服务间的网络调用,并发送到不同的监视工具,如Prometheus。


文章转载自编程阁楼,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论