Search code examples
performancewcfwcf-binding

WCF Service Timeout - Service Takes Minutes to respond to simple request


We have a simple service configured as such:

<configuration>
  <connectionStrings>
    <add name="CONN" connectionString="Server=MYSERVER,1433;Database=mydb;User Id=user;Password=pass;"/>
  </connectionStrings>
  <system.web>
    <customErrors mode="Off"/>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      </assemblies>
    </compilation>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyNamespace.MyService">
        <host>
          <baseAddresses>
            <add baseAddress="https://mywebsite.com/TestService/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" contract="MyNameSpace.IMyService" bindingConfiguration="defaultBinding" bindingNamespace="MyNameSpace"/>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding name="defaultBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647"
    maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

The service was timing out before I added the additional arguments to binding name="defaultBinding" (closeTimeout, openTimeout, receiveTimeout, sendTimeout, maxbuffersize, maxreceivedmessagesize).

Our server has only TLS1.2 enabled. The service is hosted in IIS and certificates seem to be okay - browsing the WSDL in the web looks okay.

Using SOAPUI on the same machine machine as the service is hosted times out (I assume this would be really quick?)

Is there a web config setting I am not aware of or does this come down to the server machine or possibly IIS?

Requests can take minutes to complete - even simple ones like a GetVersion() call that just returns a string. We even rebooted the machines, IIS, etc. and tried new requests - same issue.


Solution

  • Turns out my GetVersion() call actually had a LogActivity() call that would log to the database. The connection string in web.config was incorrect causing the database connection to spin until the database connection times out. The database connection timeout is set higher than the timeout for the service/client so the client would timeout before the database timeout occurred. The database connection timeout happens silently as there is no need to log a failed logging attempt for us.

    Fixing the connection string has the service responding quickly.

    Moral of the story: Double check your functions - even if they seem simple they might be doing some other stuff under the hood :)