【问题标题】:Is there a way to check availability of the services defined in the App.config <system.serviceModel> section?有没有办法检查 App.config <system.serviceModel> 部分中定义的服务的可用性?
【发布时间】:2011-07-06 14:57:52
【问题描述】:

我有一个消耗大量 WCF 服务的大型项目。端点在我的 App.config 文件的 &lt;system.serviceModel&gt; 部分中定义。

我们可以通过以下方式枚举这些端点:
ClientSection clientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;

有没有办法以某种方式“ping”这些端点中的每一个,以确保其背后的服务处于活动状态(或不活动)?我不想为每个服务显式实现 Ping() 方法并调用它来检查服务可用性(实际上,我不能这样做,因为我的项目使用的一些 WCF 服务是第三方服务)。我只想确保 App.config 中的每个端点都工作(或不工作),而不通过服务代理调用任何服务方法。

【问题讨论】:

    标签: .net wcf monitoring


    【解决方案1】:

    如果不实现特定的“监视器”接口,我能想到的最简单的方法是使用端点地址使用 WebRequest(假设 http WCF)或 Ping(假设 tcp WCF)执行标准 GET。

    如果使用http,这至少会确认服务是可访问的,但不会太多。

    如果使用 tcp,ping 只会确认主机可用。

    Ping 示例; http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx

    WebRequest 示例; http://msdn.microsoft.com/en-us/library/system.net.webrequest(v=vs.71).aspx

    【讨论】:

      【解决方案2】:

      您可以通过修改配置文件将发现端点添加到您的服务。然后您将能够查询本地网络(通过UDP Ad-hoc discovery)以查找(或确认存在)提供您正在寻找的特定服务合同的服务。

      服务的配置文件如下所示:

       <system.serviceModel>
      <services>
        <service name="MyServiceLibrary.Service1">
          <host>
            <baseAddresses>
              <!--Use * instead of localhost, so that the URI returned by discovery will display the machine name correctly-->
              <add baseAddress = "net.tcp://*:8887/Design_Time_Addresses/MyServiceLibrary/Service1/" />
              <add baseAddress = "http://localhost:8732/Design_Time_Addresses/MyServiceLibrary/Service1/" />
            </baseAddresses>
          </host>
          <endpoint address="" binding="netTcpBinding" contract="MyServiceLibrary.IService1">
            <identity>
              <dns value="localhost"/>
            </identity>
          </endpoint>
          <!--This is the endpoint used in service discovery-->
          <endpoint name ="udpDiscovery" kind ="udpDiscoveryEndpoint" />
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior>
            <serviceMetadata httpGetEnabled="True"/>
            <serviceDebug includeExceptionDetailInFaults="False" />
            <!--This denotes that the service should allow the discovery behavior-->
            <serviceDiscovery />
          </behavior>
        </serviceBehaviors>
      </behaviors>
      

      客户端上的代码会是这样的:

       DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
       FindResponse response = discoveryClient.Find(new FindCriteria(typeof(ServiceReference1.IService1)));
      
       if (response.Endpoints.Count > 0)
       {
           foreach (EndpointDiscoveryMetadata metaData in response.Endpoints)
           {
             // Add whatever logic you want to use to find the expected endpoint
           }
       }
      

      优点是你可以添加搜索条件来具体描述你要查找的服务。 ad-hoc UDP 的唯一问题是它可能有点慢。您可以通过提供来自专用发现服务器的服务信息来提高速度。

      【讨论】:

      • 感谢您的回复。曾经想过用Discovery server来监控服务状态,但是这种方式存在一些大问题: 1、不能修改第三方服务的配置。 2.如果服务出现意外故障(网络问题/电源问题/其他),它不会向Discovery服务器发送Bye公告。
      • 端点上使用了哪些绑定?如果他们启用了reliable sessions,那么这将为您提供一些额外的选项来检测服务意外故障的事件(客户端可以在频道上订阅的故障事件)。您也许可以通过创建一个代理、调用 proxy.Open() 并捕获 endpointNotFound 异常来测试服务的代理?
      猜你喜欢
      • 2013-07-26
      • 2010-11-09
      • 2014-05-31
      • 2012-01-02
      • 2022-01-25
      • 1970-01-01
      • 2019-09-05
      • 2012-10-25
      • 2013-05-19
      相关资源
      最近更新 更多