Distributed Application Runtime Dapr: Everything API

Dapr is the acronym for Distributed Application Runtime. Regarding multi-runtime, you can take a look at Bilgin Ibryam's Multi-Runtime Microservices Architecture . If you don't want to read it in English, you can take a look at my previous translation.

Dapr is a distributed system toolkit that provides APIs to decouple applications from peripheral components, allowing developers to focus more on business logic research and development. Decoupling is also a big difference from traditional SDKs. Capabilities are no longer provided by adding libraries to the application, but are provided through the sidecar (sidecar) runtime near the application (sidecar is not the well-known service mesh sidecar-pod Containers in , but a pattern widely used in system software design, such as operating systems initd, log collection components, and even multi-threading in Java.). Therefore, the Dapr sidecar mentioned here may be an independent process or a container in a pod.

In Dapr we can see the capabilities of many common SDKs:

The above capabilities are exposed to applications through HTTP and gRPC APIs. These APIs are called building blocks in Dapr , and they only provide abstractions , which means you can replace the underlying implementation (also called components in Dapr ) at will. No need to modify any application code.

For example, if your application needs to save state in storage, you can use memory as a storage component during development . In other environments, you can use persistence components such as Mysql and Redis .

Next, use the official getting started guide to experience Dapr. Dapr provides a variety of getting started guides , here I chose hello-kubernetes , but the actual operation may be slightly different from the official one, and these differences can help me understand more about Dapr.

environment

Install Dapr CLI

Dapr CLI is a tool for operating Dapr. It can be used to install, manage Dapr instances, and debug. Refer to the official installation documentation . I am using macOS and choose homebrew to install.

brew install dapr-cli

The latest version is 1.9.1.

dapr version
CLI version: 1.9.1
Runtime version: n/a

Create a Kubernetes cluster

Use k3s v1.23.8+k3s2 as the experimental environment cluster.

export INSTALL_K3S_VERSION=v1.23.8+k3s2
curl -sfL https://get.k3s.io | sh -s - --disable traefik --disable servicelb  --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config

Install Dapr

Execute the following command to install Dapr into the cluster.

dapr init --kubernetes  --wait

Check whether the components are functioning properly. In the Kubernetes environment, many of our commands use --kubernetesthe or -kparameter.

dapr status -k
  NAME                   NAMESPACE    HEALTHY  STATUS   REPLICAS  VERSION  AGE  CREATED
  dapr-dashboard         dapr-system  True     Running  1         0.11.0   47s  2023-02-11 08:30.25
  dapr-sentry            dapr-system  True     Running  1         1.9.6    47s  2023-02-11 08:30.25
  dapr-sidecar-injector  dapr-system  True     Running  1         1.9.6    47s  2023-02-11 08:30.25
  dapr-operator          dapr-system  True     Running  1         1.9.6    47s  2023-02-11 08:30.25
  dapr-placement-server  dapr-system  True     Running  1         1.9.6    47s  2023-02-11 08:30.25

sample application

After the environment is deployed, let's take a look at the sample application to be used.

git clone https://github.com/dapr/quickstarts
cd quickstarts/tutorials/hello-kubernetes

The example includes 2 applications pythonappand nodeappRedis.

  • nodeappProvides HTTP endpoints to create and query orders, and order information is stored in Redis
  • pythonappWill continue to access nodeappthe HTTP endpoint of to create orders

Two functions of Dapr are used: service invocation and state storage.

Create application namespace

The application will be deployed dpar-testunder the namespace.

kubectl create namespace dapr-test

state storage

Redis is used for state storage. First deploy Redis to the namespace store. For simplicity, only use a single master node and set a password changeme.

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install redis bitnami/redis --namespace store --create-namespace \
  --set replica.replicaCount=0 \
  --set auth.password=changeme

Create component

Since Redis sets a password, Dapr needs to provide the password to access Redis and pass it through Secret. Secret is saved dapr-testunder .

kubectl create secret generic redis -n dapr-test --from-literal=redis-password=changeme

Create components according to the Redis store specificationdapr-test under statetore:

  • The component type typeisstate.redis
  • Versionversion=v1
  • addressredisHost=redis-master.store:6379
  • The access password of Redis is obtained from redisthe key of the secret keyredis-password
  • auth.secretStoreThe type of specified key storage isKubernetes
kubectl apply -n dapr-test -f - <<EOF
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: redis-master.store:6379
  - name: redisPassword
    secretKeyRef:
      name: redis
      key: redis-password
auth:
  secretStore: kubernetes
EOF

Access state storage

Access state storage through Dapr API , request format: POST http://localhost:<daprPort>/v1.0/state/<storename>.

Below is an interception nodeappof part of the code in , stateStoreNamewhich was created above statestore. The application and component are in the same namespace, so just use them directly statestore; otherwise, you need to code the namespace where the component is located storeName.storeNamespace(since the component name is hard-coded in the code statestore, the component is created in the same namespace).

const stateStoreName = `statestore`;
const stateUrl = `http://localhost:${daprPort}/v1.0/state/${stateStoreName}`;

const state = [{
    key: "order",
    value: data
}];

const response = await fetch(stateUrl, {
    method: "POST",
    body: JSON.stringify(state),
    headers: {
        "Content-Type": "application/json"
    }
});

service call

The caller pythonapp's code.

  • Access the HTTP API through the sidecar daprd's address localhostand port .3500
  • dapr-app-idSpecify the target application id in the request header nodeapp. dapr.io/app-idThe application ID is set through Kubernetes annotations . For more annotations, please refer to the documentation .
  • The target method name is specified via the request path:/neworder
dapr_port = os.getenv("DAPR_HTTP_PORT", 3500)
dapr_url = "http://localhost:{}/neworder".format(dapr_port)

n = 0
while True:
    n += 1
    message = {"data": {"orderId": n}}

    try:
        response = requests.post(dapr_url, json=message, timeout=5, headers = {"dapr-app-id": "nodeapp"} )
        if not response.ok:
            print("HTTP %d => %s" % (response.status_code,
                                     response.content.decode("utf-8")), flush=True)
    except Exception as e:
        print(e, flush=True)

    time.sleep(1)

Deploy application

kubectl apply -n dapr-test -f deploy/node.yaml
kubectl wait --for=condition=ready pod -n dapr-test -l app=node --timeout=60s
kubectl apply -n dapr-test -f deploy/python.yaml
kubectl wait --for=condition=ready pod -n dapr-test -l app=python --timeout=60s

Checking the log of the node container, we can see that pythonappthe request from was received and the order was successfully persisted and stored.

kubectl logs -f -n dapr-test -l app=node -c node

Successfully persisted state for Order ID: 1
Got a new order! Order ID: 1
Successfully persisted state for Order ID: 2
Got a new order! Order ID: 2
Successfully persisted state for Order ID: 3
Got a new order! Order ID: 3
Successfully persisted state for Order ID: 4
Got a new order! Order ID: 4

Debug

The original official guideline was to deploy Redis and the application in the same namespace, and the storage component name was hard-coded in nodeapp. During my experiment, Redis was deployed in another space. When I checked the node container log, I saw:

Got a new order! Order ID: 1
Failed to persist state.

daprdIn the container, there is only the following log.

time="2023-02-11T02:55:38.166259509Z" level=info msg="HTTP API Called: POST /v1.0/state/statestore" app_id=nodeapp instance=nodeapp-857cf6f985-jnmzw scope=dapr.runtime.http-info type=log useragent="node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" ver=1.9.6

Let the container output debug logs by nodeappadding annotations to the pod .dapr.io/log-level="debug"daprd

time="2023-02-11T03:05:07.663028821Z" level=debug msg="{ERR_STATE_STORE_NOT_CONFIGURED state store is not configured}" app_id=nodeapp instance=nodeapp-59b754ff54-c4x4s scope=dapr.runtime.http type=log ver=1.9.6

For more debugging methods, refer to the official Troubleshooting documentation .

Summarize

Dapr provides a different method from the traditional SDK method to achieve system integration, allowing developers to focus on business logic without considering the underlying implementation; for organizations, applications become more portable and can use different cloud environments.

However, Dapr itself cannot cross clouds and clusters. The community is considering integrating with the service grid to realize service invocation in a hybrid multi-cloud environment. You can look forward to it.

Articles are published uniformly on the public account云原生指北

The web version of Windows 12 deepin-IDE compiled by junior high school students was officially unveiled. It is known as "truly independently developed" QQ has achieved "three-terminal simultaneous updates", and the underlying NT architecture is based on Electron QQ for Linux officially released 3.2.0 "Father of Hongmeng" Wang Chenglu : Hongmeng PC version system will be launched next year to challenge ChatGPT, these 8 domestic AI large model products GitUI v0.24.0 are released, the default wallpaper of Ubuntu 23.10, a Git terminal written in Rust, is revealed, the "Tauren" in the maze JetBrains announces the WebStorm 2023.3 roadmap China Human Java Ecosystem, Solon v2.5.3 released
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/5110404/blog/8483445