尝试通过ServiceStack.Redis读取Redis列表时,间歇性出现以下错误:“无法从传输连接读取数据:已建立的连接被主机中的软件中止了”。我想知道我如何使用ServiceStack可靠地连接和池化Redis的整个概念是否是错误的。这是我使用密封类和单例模式进行连接的代码:
public sealed class RedisClientBase
{
public BasicRedisClientManager Redis;
private static readonly RedisClientBase instance = new RedisClientBase();
private RedisClientBase()
{
Redis = new BasicRedisClientManager("mypassword@localhost:6379");
}
public static RedisClientBase Instance
{
get
{
return instance;
}
}
}
然后,我实例化另一个使用单例的类:
public class RedisBarSetData
{
private static RedisClient Redis;
protected IRedisTypedClient<BarSet> redisBarSetClient;
protected string instrument_key;
public RedisBarSetData()
{
Redis = (RedisClient)RedisClientBase.Instance.Redis.GetClient();
redisBarSetClient = Redis.As<BarSet>();
}
~RedisBarSetData()
{
if (Redis != null)
Redis.Dispose();
}
public List<BarSet> getData(BarSets data)
{
setKeys(data); // instrument_key is set in here
var redisBarSetClientList = redisBarSetClient.Lists[instrument_key];
List<BarSet> barSetData;
barSetData = redisBarSetClientList.GetAll(); // <-- exception here (sometimes)
return(barSetData);
}
}
这又是从“服务” DTO回调中实例化和调用的:
public class JmaSetsService : Service
{
public object Get(JmaSets request)
{
RedisBarSetData barSetData = new RedisBarSetData();
BarSets barSets = new BarSets(request);
barSetList = barSetData.getData(barSets);
return barSetList;
}
}
然后,我使用“邮递员”发布到该路线。多数点击“发送”会返回数据。有些例外。例外是尝试从代码中以注释“
<-例外”指示的redis读取内容时。现在,另一点是,我最近通过设置配置文件将Redis配置为使用密码。我提到这一点是因为我之前不记得有这个问题,但这也不可能相关,不知道。
就释放Redis连接而言,我的想法是我的析构函数调用Redis。当RedisBarSetData()超出范围时处置。这是处理它的可靠方法还是有更好的方法?我看到有人在获得池化客户端时使用“
using”语句,但是我在类中只有一个地方有很多“ using”语句,而不是调用:“ Redis
=(RedisClient)RedisClientBase.Instance.Redis .GetClient();”
如果我有很多用于该类的方法,那么我必须在每个方法中重复执行代码吗?
您不应持有RedisClient
或IRedisTypedClient<BarSet>
封装了非线程安全的Redis
TCP连接的任何单例实例。相反,您可以保留-的单例实例,IRedisClientsManager
这是提供线程安全的Redis Client
Factory(如数据库连接池)的目的。
如果您还使用ServiceStack
Services,则在ServiceStack的IOC中注册依赖项会更容易,因此IRedisClientsManager
可以像其他任何依赖项一样注入,例如AppHost.Configure()
:
container.Register<IRedisClientsManager>(c =>
new BasicRedisClientManager("mypassword@localhost:6379"));
这将允许您base.Redis
在ServiceStack Services中使用RedisClient属性,例如:
public class JmaSetsService : Service
{
public object Get(JmaSets request)
{
var redisBarSets = base.Redis.As<BarSet>();
return redisBarSets.Lists[instument_key].GetAll();
}
}
如果您使用base.Redis
,则不必显式处理RedisClient,因为它已经
由Service自动处理,即:
public class Service
{
...
public virtual void Dispose()
{
if (redis != null)
redis.Dispose();
...
}
}
您还可以IRedisClientsManager
像其他任何依赖项一样,使用公共属性或Constructor参数将其注入自己的类中,例如:
public class RedisBarSetData
{
public virtual IRedisClientsManager RedisManager { get; set; }
private IRedisClient redis;
public virtual IRedisClient Redis
{
get { return redis ?? (redis = RedisManager.GetClient()); }
}
public override void Dispose()
{
if (redis != null)
redis.Dispose();
}
public List<BarSet> getData(BarSets data)
{
setKeys(data); // instrument_key is set in here
return Redis.As<BarSet>().Lists[instrument_key].GetAll();
}
}
然后,您可以使用以下方法在ServiceStack的IOC中进行注册和自动连线:
container.RegisterAutoWired<RedisBarSetData>();
然后,您可以将其用作服务中的依赖项:
public class JmaSetsService : Service
{
public RedisBarSetData RedisBarSetData { get; set; }
public object Get(JmaSets request)
{
return RedisBarSetData.getData(new BarSets(request));
}
}
创建您自己的基类的一种替代方法是从预先存在的LogicBase基类继承,该基类已经具有
IRedisClientsManager
属性并且位于样板之上。
问题内容: 我经常收到ServiceStack.Redis:无法连接:sPort:0或ServiceStack.Redis:无法连接:sPort:50071(或其他端口号)。 当我们的网站繁忙时,似乎会发生这种情况。Redis本身看起来很好,CPU或内存使用量并未真正增加。 我正在使用连接池,并尝试更改超时值,但未成功。 用法是这样的: 问题答案: 这是由于Redis在Hyper-V上作为虚拟机托
问题内容: 有时候(并非总是如此) “无法连接:sPort:0” 使用ServiceStack.Redis尝试从Redis获取值时出错。有人知道这意味着什么吗?我正在使用PooledRedisClientManager来获取客户端。 问题答案: 我相信您可以通过增加池的来解决此问题。我将其设置为非常低的时间(10毫秒),因此,在创建池时,某些客户端在短时间内无法连接。如果池返回了这些客户机之一,它
我正在尝试推出一个WatiN开发的网络机器人(通过火狐)。它在我的电脑上启动并运行得很好(即使没有以管理员身份启动),但是当我从我的VPS(我不是管理员)启动它时,Firefox和我的应用程序立即崩溃。 控制台显示(我是从法语翻译过来的): 未处理的异常:System.IO.IOException:无法从传输连接读取数据:远程主机强制关闭了一个现有连接。---->System.Net.Socket
问题内容: 我正在编写一个连接到servlet的程序,这要感谢a,但是我在检查url时卡住了 我得到了错误: java.net.ProtocolException:读取输入后无法写入输出。 如果我用注释中的代码检查网址,但不幸的是它可以正常工作,我需要检查网址,所以我认为问题出在方法上,但我不知道如何解决 非常感谢你 问题答案: HTTP协议基于请求-响应模式:首先发送请求,然后服务器响应。服务器
问题内容: 我一周前开始使用Java,现在我想在窗口中插入一个图像。无论我尝试什么,我都会在Eclipse中继续使用它: javax.imageio.IIOException:无法读取输入文件! } 我认为代码很容易解释。我试图解决这个问题 我想做的是一个桌面程序,我的源代码存储如下:training / src / graphics / Window training / src / src /