通过StackExchange.Redis连接到Redis服务器

5
我尝试使用在Linux Ubuntu虚拟机上安装的Redis服务器创建一个测试项目。该Linux机器通过Virtual Box的桥接适配器与本地网络连接,而Virtual Box运行在我的开发Windows 7机器上。
这是一个新的Linux机器,刚刚创建完成,我进行了一些...
sudo ufw enable

然后重新启动了 Redis 服务器(在 Linux 上)。

现在,这是我在 Windows 上的尝试。

C:\Users\my-user>nmap -p 6379 10.14.30.51
Starting Nmap 7.70 ( https://nmap.org ) at ...
Nmap scan report for 10.14.30.51
Host is up (0.0010s latency).

PORT     STATE    SERVICE
6379/tcp filtered redis
MAC Address: 08:00:27:98:94:49 (Oracle VirtualBox virtual NIC)

我使用 Visual Studio 2017 创建了一个新的 .NET MVC 项目,以下是控制器的代码:

using StackExchange.Redis;
using System.Web.Mvc;

namespace RedisClient.Controllers
{
    public class HomeController : Controller
    {
        public struct Server {
            public const string IP = "10.14.30.51";
            public const int Port = 6379;
        }

        public ActionResult Index() { return View(); }

        public ActionResult About()
        {            
            ConnectionMultiplexer redis = 
                ConnectionMultiplexer.Connect($"{Server.IP}:{Server.Port}"); 

            IDatabase db = redis.GetDatabase();
            string value = "abcdefg";
            db.StringSet("mykey", value);
            value = db.StringGet("mykey");

            ViewBag.Message = $"The value is '{value}'";

            return View();
        }

        public ActionResult Contact() { return View(); }
    }
}

所以,当我点击“关于”链接时,在.Connect行上出现以下错误:

无法连接到Redis服务器。UnableToConnect on 10.14.30.51:6379/Interactive,初始化/未启动,最近:NONE,来源:BeginConnectAsync,未完成:0,最后阅读时间:0秒前,最后写入时间:0秒前,保持活动状态:60秒,状态:连接中,管理器:10个可用,最后心跳:从未,全局:0秒前,版本:2.0.601.3402

--编辑

输出为

var log = new StringWriter();

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(
    $"{Server.IP}:{Server.Port},abortConnect=False", log);
var logOutput = log.ToString();

以下是:

10.14.30.51:6379,abortConnect=False

Connecting 10.14.30.51:6379/Interactive...
BeginConnect: 10.14.30.51:6379
1 unique nodes specified
Requesting tie-break from 10.14.30.51:6379 > __Booksleeve_TieBreak...
Allowing endpoints 00:00:05 to respond...
Awaiting task completion, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=1,Free=8190,Min=4,Max=8191)
Not all tasks completed cleanly (from ReconfigureAsync#1524, timeout 5000ms), IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=4,Free=8187,Min=4,Max=8191)
10.14.30.51:6379 did not respond
Waiting for tiebreakers...
Awaiting task completion, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=4,Free=8187,Min=4,Max=8191)
connection failed: 10.14.30.51:6379 (Subscription, UnableToConnect): UnableToConnect on 10.14.30.51:6379/Subscription, Initializing/NotStarted, last: NONE, origin: BeginConnectAsync, outstanding: 0, last-read: 5s ago, last-write: 5s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 0s ago, v: 2.0.601.3402
connection failed: 10.14.30.51:6379 (Interactive, UnableToConnect): UnableToConnect on 10.14.30.51:6379/Interactive, Initializing/NotStarted, last: NONE, origin: BeginConnectAsync, outstanding: 0, last-read: 5s ago, last-write: 5s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 0s ago, v: 2.0.601.3402
Finished awaiting tasks, IOCP: (Busy=2,Free=998,Min=4,Max=1000), WORKER: (Busy=4,Free=8187,Min=4,Max=8191)
10.14.30.51:6379 failed to nominate (Faulted)
> UnableToConnect on 10.14.30.51:6379/Interactive, Initializing/NotStarted, last: NONE, origin: BeginConnectAsync, outstanding: 0, last-read: 5s ago, last-write: 5s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 0s ago, v: 2.0.601.3402
No masters detected
10.14.30.51:6379: Standalone v2.0.0, master; keep-alive: 00:01:00; int: Connecting; sub: Connecting; not in use: DidNotRespond
10.14.30.51:6379: int ops=0, qu=0, qs=0, qc=0, wr=0, socks=2; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=2
Circular op-count snapshot; int: 0 (0,00 ops/s; spans 10s); sub: 0 (0,00 ops/s; spans 10s)
Sync timeouts: 0; async timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
resetting failing connections to retry...
retrying; attempts left: 2...
1 unique nodes specified
Requesting tie-break from 10.14.30.51:6379 > __Booksleeve_TieBreak...
Allowing endpoints 00:00:05 to respond...
Awaiting task completion, IOCP: (Busy=1,Free=999,Min=4,Max=1000), WORKER: (Busy=2,Free=8189,Min=4,Max=8191)
Not all tasks completed cleanly (from ReconfigureAsync#1524, timeout 5000ms), IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=2,Free=8189,Min=4,Max=8191)
10.14.30.51:6379 did not respond
Waiting for tiebreakers...
Awaiting task completion, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=2,Free=8189,Min=4,Max=8191)
Not all tasks completed cleanly (from NominatePreferredMaster#1761, timeout 50ms), IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=2,Free=8189,Min=4,Max=8191)
10.14.30.51:6379 failed to nominate (WaitingForActivation)
No masters detected
10.14.30.51:6379: Standalone v2.0.0, master; keep-alive: 00:01:00; int: Disconnected; sub: Disconnected; not in use: DidNotRespond
10.14.30.51:6379: int ops=0, qu=0, qs=0, qc=0, wr=0, socks=2; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=2
Circular op-count snapshot; int: 0 (0,00 ops/s; spans 10s); sub: 0 (0,00 ops/s; spans 10s)
Sync timeouts: 0; async timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
resetting failing connections to retry...
retrying; attempts left: 1...
1 unique nodes specified
Requesting tie-break from 10.14.30.51:6379 > __Booksleeve_TieBreak...
Allowing endpoints 00:00:05 to respond...
Awaiting task completion, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=2,Free=8189,Min=4,Max=8191)
Not all tasks completed cleanly (from ReconfigureAsync#1524, timeout 5000ms), IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=5,Free=8186,Min=4,Max=8191)
10.14.30.51:6379 did not respond
Waiting for tiebreakers...
Awaiting task completion, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=5,Free=8186,Min=4,Max=8191)
Finished awaiting tasks, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=2,Free=8189,Min=4,Max=8191)
10.14.30.51:6379 failed to nominate (Faulted)
> UnableToConnect on 10.14.30.51:6379/Interactive, Initializing/NotStarted, last: NONE, origin: BeginConnectAsync, outstanding: 0, last-read: 5s ago, last-write: 5s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 10s ago, v: 2.0.601.3402
No masters detected
10.14.30.51:6379: Standalone v2.0.0, master; keep-alive: 00:01:00; int: Disconnected; sub: Disconnected; not in use: DidNotRespond
10.14.30.51:6379: int ops=0, qu=0, qs=0, qc=0, wr=0, socks=3; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=3
Circular op-count snapshot; int: 0 (0,00 ops/s; spans 10s); sub: 0 (0,00 ops/s; spans 10s)
Sync timeouts: 0; async timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
Starting heartbeat...

我是一名有用的助手,可以翻译文本。

参考资料

在我的.csproj文件中,我有其他内容

<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
  <HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
...
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
  <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
...
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
  <HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>

这里有一个相关的SuperUser问题,其中包含其他细节

Windows: 在此输入图像描述

Linux: 在此输入图像描述


我投票关闭此问题,因为它已经在超级用户上做了交叉发布。 - Giacomo1968
1
或者更简单地说,如果您有Redis工具可用:redis-cli -h 10.14.30.51 -p 6379 ping - Marc Gravell
1
@Serge 不,我给你的第一个选项只使用 telnet - 没有任何与 redis 相关的东西,只是一个命令行套接字终端;但是:如果你要处理大量的 redis,如果你有 redis 工具可用,它将节省你很多时间;你可以从 choco 获取 Windows 构建[https://chocolatey.org/packages/redis-64],但我个人使用 WSL 和主要的 Linux redis 发行版 在 Windows 上redis-cli 是与 redis 交互的默认 REPL 工具。 - Marc Gravell
1
我从你提供的链接中使用choco安装了工具,同时我也更新了OP并附上了nmap命令和你给我的"redis-cli... ping"命令的截图。但是这个命令没有任何反馈,似乎端口被某个未知应用程序过滤了,即使在Windows或Linux虚拟机上也是如此。我已经禁用了防火墙,问题可能出在其他地方。 - serge
1
@Serge 在操作系统能够连接之前,库就没有机会——所以...抱歉,你必须找到问题的根源,但在 redis-cli ... ping 能够正常工作之前,这不是一个库的问题。 - Marc Gravell
显示剩余6条评论
2个回答

5
感谢这篇SF答案,我成功实现了Windows主机和虚拟Linux机器的通信。
我所采取的步骤如下: 在Redis服务器(Linux)上: 1) 输入ss -tlnp 'sport == :6379'。如果在这些行中找到127.0.0.1或者::1,则应该编辑redis.config文件,在配置文件中注释掉bind 127.0.0.1 ::1(如果尚未注释),并且不要忘记在更改配置后重新启动redis
如果看到类似于0.0.0.0:6379的内容,则进行下一步操作。
2) 在同一配置文件中检查Redis的protected mode是否启用。如果启用并且您想保留它,则可以在Redis配置文件中使用requirepass <yourConnectionPassToUseOnClientConnectionString>
3) 检查客户端IP地址(在我的情况下是Windows客户端计算机)。将其添加到Linux的iptables中:
iptables -A INPUT --src <clientIpAddress> -p tcp --dport 6379 -j ACCEPT

为了使这个添加的条目持久化,请参见如何在这里保存iptables状态。

在客户端(Windows)机器上:

4) 在连接字符串中使用上述密码连接到Linux Redis服务器。

ConnectionMultiplexer redis = 
  ConnectionMultiplexer.Connect($"{Server.IP}:{Server.Port},resolvedns=1,abortConnect=False,password={Server.Password}");

5*) 可选地,你可以从 choco (在Windows上安装)中获取Windows版本的Redis。使用cmd测试客户端Windows上的连接。

redis-cli -h <LinuxServerIP> -p 6379 ping

1
这件事最好向库的github页面询问;而我会在那之后提出一个问题:请这样做:
var log = new StringWriter();

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(
    $"{Server.IP}:{Server.Port},abortConnect=False", log);
var logOutput = log.ToString();

并告诉我们logOutput是什么。

我猜可能是:

  • 由于防火墙规则,没有TCP访问权限
  • 如果您使用的是.NET Framework,则可能存在程序集绑定问题

后者可能更有可能出现问题,通常的解决方法是在以下内容中添加明确的<PackageReference>引用:

  • System.Buffers (>= 4.4.0)
  • System.Runtime.CompilerServices.Unsafe (>= 4.5.2)

即:

<PackageReference Include="System.Buffers" Version="4.5.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />

可能还有其他原因(因为...)

<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />

基本上,Nuget 在处理传递依赖和上述 Microsoft 库时存在一些问题。这超出了我的控制范围。

@Serge,但这并不会打开防火墙的漏洞。 - Marc Gravell
我也执行了 "sudo ufw enable"。 - serge
我想你应该知道,更多细节(以及配置文件)在我的那个 SuperUser 问题中 https://superuser.com/q/1435346/465922。 - serge
1
@Serge,请不要像这样将问题同时发布到超级用户和Stack Overflow上。这只会引起混乱,导致人们不会真正认真对待你的问题和相关努力。 - Giacomo1968
@MarcGravell,问题已解决,请看我的回答,非常感谢您的时间,您提供的步骤在寻找答案时对我很有帮助! - serge
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接