docker - StackExchange.Redis.RedisConnectionException : No connection (requires writable - not eligible for replica)

标签 docker .net-core redis digital-ocean stackexchange.redis

我在我的项目中使用了Redis 版本2.6.66DotNet Core 6.0。 该项目在本地运行良好,但部署到 cloud.digitalocean.com 后 我收到错误。

如何解决?

错误:

fail: API.Middleware.ExceptionMiddleware[0] No connection (requires writable - not eligible for replica) is active/available to service this operation: SETEX /api/products|pageIndex-1|pageSize-6|sort-name, mc: 1/1/0, mgr: 10 of 10 > StackExchange.Redis.RedisConnectionException: No connection (requires writable - not eligible for replica) is active/available to service this operation: SETEX /api/products|pageIndex-1|p> at StackExchange.Redis.ConnectionMultiplexer.ThrowFailed[T](TaskCompletionSource`1 source, Exception unthrownException) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1836 --- End of stack trace from previous location --- at Infrastructure.Services.ResponseCacheService.CacheResponseAsync(String cacheKey, Object response, TimeSpan timeToLive) in C:\Workspace\MainProjects\eshop\sigma-backend-dotnet\sigma> at API.Helpers.CachedAttribute.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in C:\Workspace\MainProjects\eshop\sigma-backend-dotnet\sigma\API\He> at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope,> at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Obje> at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boo> at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at API.Middleware.ExceptionMiddleware.InvokeAsync(HttpContext context) in C:\Workspace\MainProjects\eshop\sigma-backend-dotnet\sigma\API\Middleware\ExceptionMiddleware.cs:line 47

error

docker-compose 配置:

services:

  redis:
    image: redis:latest
    ports:
      - 6379:6379
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis-data:/data

  redis-commander:
    image: rediscommander/redis-commander:latest
    environment:
      - REDIS_HOSTS=local:redis:6379
      - HTTP_USER=XXX
      - HTTP_PASSWORD=YYY
    ports:
      - 8081:8081
    depends_on:
      - redis

    
volumes:
  redis-data:

程序.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IConnectionMultiplexer>(c =>
{
    var configuration = ConfigurationOptions.Parse(builder.Configuration.GetConnectionString("Redis"), true);
    return ConnectionMultiplexer.Connect(configuration);
});

最佳答案

我按照以下说明部署了该项目:

使用 Docker 部署到 Linux - 与 .Net 6.0 一起使用

  1. 使用 Ubuntu 20.04 上的 Docker 19.03.12 创建一个带有 Digital Ocean 的新 Droplet

IP地址:您的IP地址

根用户的密码:YourPassword

  • 使用终端或 Powershell 登录 Droplet:

    ssh root@ip地址

  • 系统会要求您输入密码。输入这个。

  • 使用以下命令创建新的 docker-compose 文件:

    sudo nano docker-compose.yml

  • 复制并粘贴到 docker-compose 配置中:

  • docker-compose

  • 运行以下命令启动docker服务

    docker-compose up -d

  • 通过运行以下命令安装和配置 apache:

    sudo apt更新

    sudo apt install apache2

    a2enmod代理proxy_http proxy_html重写

    systemctl 重新启动 apache2

    sudo ufw 应用列表

    sudo ufw 允许“Apache Full”

    sudo systemctl 状态 apache2

  • 可选 - 允许端口通过防火墙,以便您通过端口管理 PostGreSQL 和 Redis。

  • sudo ufw allow 8080/tcp
    
    sudo ufw allow 8081/tcp
    
  • 测试您是否可以通过浏览以下地址访问默认的 apache 页面:http://ipaddress

  • 创建一个新目录,其中将包含我们发布的 dotnet 应用程序并向用户分配权限:

    sudo mkdir/var/skinet

    sudo chown -R $USER:$USER/var/skinet

  • 为 Skinet 应用创建一个新的配置文件:

  • sudo nano /etc/apache2/sites-available/skinet.conf
    
  • 粘贴以下配置,这将通过 Kestrel 服务器设置反向代理:
  • <VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    
  • 通过运行以下命令启用 Skinet 站点:
  • a2ensite skinet
    
    ls /etc/apache2/sites-enabled
    
    a2dissite 000-default
    
    systemctl reload apache2
    
  • 安装部署重新加载的扩展。在 .vscode 目录中创建 settings.json 文件并更新服务器的 IP 地址和密码:
  • {
        "deploy.reloaded": {
            "packages": [
                {
                    "name": "Version 1.0.0",
                    "description": "Package version 1.0.0",
    
                    "files": [
                        "publish/**"
                    ]
                }
            ],
    
            "targets": [
                {
                    "type": "sftp",
                    "name": "Linux",
                    "description": "SFTP folder",
    
                    "host": "ipaddress", "port": 22,
                    "user": "root", "password": "your password",
    
                    "dir": "/var/skinet",
                    "mappings": {
                        "publish/**": "/"
                    }
                }
            ]
        }
    }
    
  • 可选 - 将 appsettings.json 的日志记录级别更改为 Microsoft 日志记录级别的信息:
  • {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Information",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
    }
    
  • 通过在 VS Code 终端中运行以下命令重新发布更改后的应用:
  • dotnet publish -c Release -o publish skinet.sln
    
  • 使用命令面板 -> 部署重新加载 -> 部署包来部署文件

  • 添加一个端点以指向服务器的 IP 地址,并选择我们要监听的 2 个事件: payment_intent.succeeded payment_intent. payment_failed。请注意网络 Hook MY_SECRET_PASSWORD,因为我们很快就会需要它。

  • http://ipaddress/api/payments/webhook
    
  • 返回 Linux 服务器,为 kestrel 服务器创建服务配置:
  • sudo nano /etc/systemd/system/skinet-web.service
    
  • 更新显示 REPLACEME 的 API key 配置,然后将配置粘贴到 Nano 编辑器中
  • [Unit]
    Description=Kestrel service running on Ubuntu 20.04
    [Service]
    WorkingDirectory=/var/skinet
    ExecStart=/usr/bin/dotnet /var/skinet/API.dll
    Restart=always
    RestartSec=10
    SyslogIdentifier=skinet
    User=www-data
    Environment=ASPNETCORE_ENVIRONMENT=Production
    Environment='Token__Key=CHANGE ME TO SOMETHING SECURE'
    Environment='Token__Issuer=http://REPLACEME'
    Environment='StripeSettings__PublishibleKey=REPLACEME'
    Environment='StripeSettings__SecretKey=REPLACEME'
    Environment='StripeSettings__WhSecret=REPLACEME'
    Environment='ConnectionStrings__DefaultConnection=Server=localhost;Port=5432;User Id=appuser;Password=MY_SECRET_PASSWORD; Database=skinet'
    Environment='ConnectionStrings__IdentityConnection=Server=localhost;Port=5432;User Id=appuser;Password=MY_SECRET_PASSWORD; Database=identity'
    Environment='ConnectionStrings__Redis=localhost'
    Environment='ApiUrl=http://ipaddress/Content/'
    [Install]
    WantedBy=multi-user.target
    
  • 按照此处的说明安装 .Net 运行时:https://learn.microsoft.com/en-gb/dotnet/core/install/linux-ubuntu#2004-

  • 通过运行以下命令重新启动日志服务:

  • systemctl restart systemd-journald
    
  • 通过运行以下命令启动 kestrel 服务:
  • sudo systemctl start skinet-web.service
    
  • 通过运行检查它是否启动:
  • netstat -ntpl
    
  • 通过运行以下命令检查日志:
  • journalctl -u skinet-web.service --since "5 min ago"
    
  • 确保没有错误,然后测试您是否可以浏览到 http://ipaddress 上已发布的应用
  • 关于docker - StackExchange.Redis.RedisConnectionException : No connection (requires writable - not eligible for replica),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73897576/

    相关文章:

    docker - 如何持久化 alpine-nginx 日志文件?

    docker - 使用CVS启动centos docker容器时出错

    c# - 构建docker镜像的问题,RUN dotnet restore : "No such host is known" in VS2019, Windows

    redis randomKey 来自特定值?

    docker - 亚马逊ECS上的容器运输

    docker - 如何在 docker hub 上添加我不拥有的私有(private)仓库以进行自动构建

    reactjs - 如何使用 React js 将单词建议附加到机器人的聊天输入区域?

    .net-core - .NET Core中的System.Web.Services命名空间

    java - SpringBoot Redis 远程主机

    php - Laravel/docker-compose/redis - 未找到类 'Redis'