【问题标题】:State store throws exception when run from docker-compose从 docker-compose 运行时状态存储抛出异常
【发布时间】:2021-09-09 19:56:57
【问题描述】:

我有一个简单的 Dapr 项目用于状态管理。我有一个模型类保存数据并将该模型数据存储到 redis 状态存储中。我有一个statestore.yml 文件用于配置。

当我在命令行中使用dapr run --app-id [appname] --app-port [port] dontnet run 命令运行项目时,同时运行从 dockerhub 新提取的默认映像(redis、zipkin、daprio/dapr),状态存储端点工作。

但是,当我创建一个 docker-compose 并运行它时,我最终会遇到如下所示的异常。我在 Stack Overflow 上找不到确切的解决方案。有谁知道什么可能导致这个问题?

====== docker-compose.yml =======

version: '3.4'

services:
  daprtestapi:
    image: ${DOCKER_REGISTRY-}daprtestapi
    build:
      context: .
      dockerfile: DaprTestApi/Dockerfile
    ports:
     - "52000:50001"
    depends_on:
     - redis

  daprtestapi-dapr:
    image: "daprio/daprd:latest"
    command: ["./daprd", "-app-id", "daprtestapi", "-app-port", "80", "-components-path", "/DaprTestApi/Components"]
    depends_on:
        - daprtestapi
    network_mode: "service:daprtestapi"

  redis:
    container_name: "dapr_redis" 
    image: "redis:latest"

======== 抛出异常 ==============

Dapr.DaprException: State operation failed: the Dapr endpoint indicated a failure. See InnerException for details.
 ---> Grpc.Core.RpcException: Status(StatusCode="FailedPrecondition", Detail="state store is not configured")
   at Dapr.Client.DaprClientGrpc.GetStateAndETagAsync[TValue](String storeName, String key, Nullable`1 consistencyMode, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at Dapr.Client.DaprClientGrpc.GetStateAndETagAsync[TValue](String storeName, String key, Nullable`1 consistencyMode, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
   at Dapr.Client.DaprClient.GetStateEntryAsync[TValue](String storeName, String key, Nullable`1 consistencyMode, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
   at Dapr.AspNetCore.StateEntryModelBinder.GetStateEntryAsync[T](DaprClient daprClient, String storeName, String key)
   at Dapr.AspNetCore.StateEntryModelBinder.BindModelAsync(ModelBindingContext bindingContext)
   at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
:authority: localhost:57104
:method: GET
:path: /get/1
:scheme: https
Accept: text/plain
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: language=en,region=en-US
Host: localhost:57104
Referer: https://localhost:57104/swagger/index.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.38
sec-ch-ua: "Microsoft Edge";v="93", " Not;A Brand";v="99", "Chromium";v="93"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty

【问题讨论】:

  • DaprTestApi 是什么样的?您是如何尝试访问状态存储的?
  • @tmarwen DaprTestApi 是非常简单的 .net 核心 API,带有用于公开端点的控制器。我正在调用 dapr 客户端方法在 statestore 中添加数据。我也有 statestore 配置 yml。这是用于将数据添加到引发异常的 statestore 的代码。 var state = await daprClient.GetStateEntryAsync&lt;ProducerStore&gt;(StoreName, pDashboard.Id.ToString()); state.Value ??= new ProducerStore() { Id = pDashboard.Id.ToString()}; state.Value.Dashboard = pDashboard; await state.SaveAsync(); return Ok(state.Value);

标签: docker .net-core docker-compose dapr


【解决方案1】:

应该有一个 statestore.yaml 作为配置文件。而在docker-compose.yaml中,有一个“volumes”部分用于将你主机上statestore.yaml的路径映射到/DaprTestApi/Components,比如:

daprtestapi-dapr:
    image: "daprio/daprd:latest"
    command: ["./daprd", "-app-id", "daprtestapi", "-app-port", "80", "-components-path", "/DaprTestApi/Components"]
    depends_on:
        - daprtestapi
    network_mode: "service:daprtestapi"
    volumes:
        - [path for statestore.yaml]:/DaprTestApi/Components

最后,statestore.yaml 看起来像:

apiVersion: dapr.io/v1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: redis:6379
  - name: redisPassword
    value: ""

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2019-10-03
    • 1970-01-01
    • 2012-08-21
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多