首页 > 程序开发 > 综合编程 > 其他综合 >

Wcf通讯基础框架方案(五)——更新通知

2011-04-28

对于负载均衡环境,多服务器内存中缓存数据的话,需要解决的一个很重要的问题就是一旦数据库中数据有更新,怎么让缓存的数据立即更新? 如果可以容忍延迟或是差异性的话,可以考虑缓存的数据有一个过期时间。但是,最好的方式还是采用通

对于负载均衡环境,多服务器内存中缓存数据的话,需要解决的一个很重要的问题就是一旦数据库中数据有更新,怎么让缓存的数据立即更新?

如果可以容忍延迟或是差异性的话,可以考虑缓存的数据有一个过期时间。但是,最好的方式还是采用通知方式,或者说发布订阅方式。

所有的客户端会订阅客户端配置修改的消息,所有的服务端会订阅服务端配置修改的消息,配置后台在修改后复杂发布这个消息。

在这里采用redis作为发布订阅的服务端,利用TCP双工特性与所有客户端和服务端保持长连接,进行消息的推送。

string contract = "";
using (WcfConfigDataContext data = new WcfConfigDataContext())
{
var s = data.ServerFarms.First();
s.ServerFarmAddress = TextBox1.Text;
data.SubmitChanges();
contract = data.ServiceEndpoints.First().ServiceContractType;
}

using (WcfConfigDataContext data = new WcfConfigDataContext())
{
TextBox1.Text = data.ServerFarms.First().ServerFarmAddress;
}
using (var redisClient = cm.GetClient())
{
redisClient.PublishMessage("WcfConfigClientChange", contract);
}假设后台更新了服务集群的地址,势必要通知客户端来重新更新缓存的信道工厂。可以看到,在后台修改了配置之后立即向WcfConfigClientChange通道发布一个消息,消息内容就是契约的类型名。

在客户端的WcfServiceClientFactory中:

[MethodImpl(MethodImplOptions.Synchronized)]
private static void CreateRedisSubThread()
{
StartSub();
redisCheckTimer = new Timer(obj =>
{
if (((TimeSpan)(DateTime.Now - lastMsg)).Seconds > 10)
{
#if DEBUG
LocalLogService.Log("recreate redis sub thread");
#endif
try
{
redisSubThread.Abort();
}
catch
{

}
finally
{
StartSub();
}
}
}, null, 0, 5000);
}

private static void StartSub()
{
redisSubThread = new Thread(() =>
{
try
{
using (var subscription = cm.GetClient().CreateSubscription())
{
subscription.OnUnSubscribe = channel =>
{
#if DEBUG
LocalLogService.Log("OnUnSubscribe");
#endif
};
subscription.OnMessage = (channel, msg) =>
{
try
{
if (msg == "heart")
{
lastMsg = DateTime.Now;
&nb

相关文章
最新文章
热点推荐