系统上线后WCF服务最近经常死掉的原因分析总结

前言  

  最近系统上线完修改完各种bug之后,功能上还算是比较稳定,由于最近用户数的增加,不知为何经常出现无法登录、页面出现错误等异常,后来发现是由于WCF服务时不时的就死掉了。后来就开始分析问题。得到的初步解决方案如下:

  1、在Web端调用WCF服务使用后,未释放未关闭导致新的链接无法访问

  2、增加默认的连接数,系统默认的链接数比较小

  3、提供同一个WCF服务的不同实例

1、在Web端调用WCF服务使用后,未释放未关闭导致新的链接无法访问  

首先保证客户端每次建立的连接在使用完成后进行关闭。那么请不要使用传统的using语句中来调用WCF,这里@dudu大神也曾经有遇到过这个问题 http://www.cnblogs.com/dudu/archive/2011/01/18/1938144.html。对其分析也比较全面,在此不再赘述。

不过自己感觉更好的处理方式可能是下面这样,也就是将@dudu中的方法进行了简单的封装,但自己感觉还有优化的空间,暂时还没试出来。

    public static class WcfExtensions
    {
        public static void Using<T>(this T client, Action<T> work)
            where T : ICommunicationObject
        {
            try
            {
                work(client);
                client.Close();
            }
            catch (CommunicationException e)
            {
                client.Abort();
            }
            catch (TimeoutException e)
            {
                client.Abort();
            }
            catch (Exception e)
            {
                client.Abort();
            }
        }
    }

进行调用看起来是如下的方式,看上去还是比较简练了,但是感觉还是有些繁琐,不知道能不能直接一行return代码搞定?

        public static DocAppend GetDocAppend(string dwid, string actionId)
        {
            DocAppend docAppend = new DocAppend();
            new DocumentServiceV2.DocumentServiceV2Client().Using(channel => docAppend = channel.GetDocAppend(dwid, actionId));
            return docAppend;
        }

另外一种关闭链接的方式,这种方式其实和上面那种大同小异,也是可以封装的,系统中暂且就使用的上面的方式。

            Document document = null;
            DocumentServiceClient client = new DocumentService.DocumentServiceClient();
            try
            {
                document= client.GetDocument(id);
                if (client.State != System.ServiceModel.CommunicationState.Faulted)
                {
                    client.Close();
                }
            }
            catch (Exception ex)
            {
                client.Abort();
            }
            return document;

2、增加默认的连接数,系统默认的链接数比较小  

如果采用的netTcp绑定,而在windows7中,并发连接数默认是10。

这是原来的配置文件

<binding name="netTcpBindConfig" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
maxReceivedMessageSize="2147483647"> 

将项目移植到服务器上之后

<binding name="netTcpBindConfig" closeTimeout="00:30:00"
openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="100"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="100"
maxReceivedMessageSize="2147483647"> 

但有些时候还是不能解决问题,就想到是不是需要配置一下行为,于是将行为的连接数量也改变了

      <serviceBehaviors>
        <behavior name="ThrottledBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          <serviceThrottling maxConcurrentCalls="5000" maxConcurrentSessions="5000" maxConcurrentInstances="5000" />
        </behavior>
      </serviceBehaviors>

maxConcurrentCalls:在同一时刻允许处理的最大服务器操作数。如果超过次数,则需要把其他方法调用插入队列中,以等待处理。

maxConcurrentSessions:同时传输或应用程序会话的最大个数。

maxConcurrentInstances:实例的最大个数。

增加连接数量

在Http协议中,规定了同个Http请求的并发连接数最大为2. 这个数值,可谓是太小了。而目前的浏览器,已基本不再遵循这个限制,但是Dot Net平台上的 System.Net 还是默认遵循了这个标准的。从而造成了,在使用HttpWebRequset 或者 WebClient 利用多线程的方式,访问某个网站时,经常出现 连接被异常关闭 的错误,大大降低了效率。

这个限制的值,是可以自己设置或配置的。此值设置后,只对以后发起的HTTP请求有效。

  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="5000"/>
    </connectionManagement>
  </system.net>

3、提供同一个WCF服务的不同实例

3、首先查看一个WCF服务类

里面有N多构造函数的重载版本,我们来具体看一下第二个构造函数

        public DocumentWriteServiceClient(string endpointConfigurationName) :
                base(endpointConfigurationName) {
        }

即传入配置名生与代码类的实例,我们在web.config中的wcf配置节,做如下处理:

      <endpoint address="http://localhost:8700/Design_Time_Addresses/SinoSZJS.WebWCF/DocumentWriteService/"
 binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICommonBinding"
 contract="DocumentWriteService.IDocumentWriteService" name="1">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:8700/Design_Time_Addresses/SinoSZJS.WebWCF/DocumentWriteService/"
 binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICommonBinding"
 contract="DocumentWriteService.IDocumentWriteService" name="2">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost:8700/Design_Time_Addresses/SinoSZJS.WebWCF/DocumentWriteService/"
 binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICommonBinding"
 contract="DocumentWriteService.IDocumentWriteService" name="3">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>

修改客户端的调用代码

DocumentWriteServiceClient client = new DocumentWriteServiceClient();

改为

DocumentWriteServiceClient client = new DocumentWriteServiceClient(new Random().Next(1, 4).ToString());

即客户端随机从多个wcf服务端的host中挑一个,生成代码类实例,说白了就是把一个wcf的host分身成了3个,并且客户端随机调用3者之一。

如果要考虑到大量并发的情况下,伪随机数可能确实有一些问题,不过,这个应该也不难解决,自己另外写一个类似伪随机数的算法,只要保证生成指定范围内不重复的数字(或字符)就可以了。

总结 

暂时这三种方式有效地防止了WCF服务的再次挂掉,至少最近几天服务一直在稳定的运行,没有太大的异常,很是让人欣慰。不知道针对WCF服务的处理是否还有其他方式,也让博客园的大牛们来指点一二吧。

系统上线后WCF服务最近经常死掉的原因分析总结,布布扣,bubuko.com

时间: 2024-12-26 22:14:57

系统上线后WCF服务最近经常死掉的原因分析总结的相关文章

PHPWAMP自启异常,服务器重启后Apache等服务不会自动重启的原因分析

在使用"PHPWAMP自动任务"时,不少学生遇到如下问题: "phpwamp绿色集成环境重启动电脑(服务器)后,不会自动启动网站服务" (如果是其他环境或是自己搭建时遇到此问题,也是可以用此法解决) 此文章内容符合: 为什么网站服务由手动变成自动后还是无法重启? 为什么我把服务设置成自动后,开机又变回手动了? 为什么服务器(电脑)重启后服务不会自动跟着重启? windows服务器重启后网站服务不会自动重启的原因分析. 为什么服务设置成自动后,重启动服务器(电脑)服务

免费建站系统上线后反响不错

网站上线后做了一些测试就想试试看看用户反应怎么样,于是在经常逛的几个社区发了几篇文章,没想到,一天竟然带来了300多ip网站注册了30多个用户,生成网站20多个,根据几个用户的调查反映还不错,看到这些心里有了许多安慰. 说到这个系统真可谓是一波三折,其实好几年前就有这么个想法,因为一直从事网站建设的业务,总想着有一天,网站不需要一个个的做,也能够批量化生产,注册个账号,点点鼠标就成了,不需要设计师设计好几天,程序员加班好几天,一切都将变得如此的轻松,就这样今年终于下定决心做了起来,总共花费三个月

maven项目打包分析及打包后war包缺少配置文件报错的原因分析,使用progard混淆时配置分析

1.maven打包: 一直以来我都没太注意过在myeclipse下使用run as来clean居然对项目的target目录没有进行操作,要让操作有效,需要进入到maven build...选项下,进行clean,然后再使用process resources来加入配置文件,再使用compile-->package来打包,同时,值得注意的是,maven在进行打包时默认只把java文件打包进war,如果在非资源路径下,有配置文件,如mybits的mapper.xml文件,需要在maven里边指定一下,

WCF--建立简单的WCF服务

在VS2010里建立一个最简单的WCF服务,基本流程如下: 一:新建WCF应用 首先,新建一个WCF服务的应用,如下图所示 建立完成之后,VS将自动生成一个最简单的WCF工程,在这个应用中,包含了最基本Contract.Service. 工程如下: 不需要编辑任何文件,直接编译生成,得到一个WcfService1.dll文件 二.WCF应用中的契约(Contract) 在生成的WCF工程中,IService1.cs中为Contract(本例中契约和服务放在同一个工程下了,实际上也可以分为两个工程

HttpWebRequest的GetResponse或GetRequestStream超时 + 各种超时死掉的可能和相应的解决办法

用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (HttpWebResponse)req.GetResponse(); 之前的多次调试,一直都是可以正常获得对应的response,然后读取html页面的. 但是后来几次的调试,在没有改变代码的前提下,结果GetResponse却始终会超时死掉. 1.默认request的timeout是1000000毫秒=100秒,都

(转载)HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

原文链接:http://www.crifan.com/fixed_problem_sometime_httpwebrequest_getresponse_timeout/ [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (HttpWebResponse)req.GetResponse(); 之前的多次调试,一直都是可以正常获得对应的response,然后读

HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

[问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (HttpWebResponse)req.GetResponse(); 之前的多次调试,一直都是可以正常获得对应的response,然后读取html页面的. 但是后来几次的调试,在没有改变代码的前提下,结果GetResponse却始终会超时死掉. [解决过程] 1.默认request的timeout是1000

【转载】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

[问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (HttpWebResponse)req.GetResponse(); 之前的多次调试,一直都是可以正常获得对应的response,然后读取html页面的. 但是后来几次的调试,在没有改变代码的前提下,结果GetResponse却始终会超时死掉. [解决过程] 1.默认request的timeout是1000

WCF服务发布到IIS中去(VS2013+win7系统)

第一个WCF程序 1. 新建立空白解决方案,并在解决方案中新建项目,项目类型为:WCF服务应用程序.建立完成后如下图所示: 2.删除系统生成的两个文件IService1.cs与Service1.svc. 3.添加自定义的WCF[服务文件]User.svc,此时vs2010会自动生成WCF接口文件IUser.cs,我们在IUser中定义WCF方法ShowName,在User.svc.cs对该接口的方法进行实现. 代码如下: using System.ServiceModel; namespace