博客
关于我
检测WCF服务是否在线(动态执行WCF服务)
阅读量:433 次
发布时间:2019-03-06

本文共 3416 字,大约阅读时间需要 11 分钟。

在我们的系统中,面对多个WCF服务的监控问题,经常会遇到某些WCF服务莫名其休止的情况。这促使我们开发了一个定时检测服务,定期检查各个WCF服务的状态。为了实现这一功能,我们需要一个通用的检测方案,而不是简单地通过引用其他WCF服务生成客户代理去逐一调用。

方案一:检测HTTP绑定的WCF服务

对于HTTP绑定的WCF服务,检测其是否在线的最简单方法是使用HttpClient发送请求到服务的地址,查看是否能获取到服务描述的XML。如果服务在线,返回的结果会包含服务描述信息;如果服务未在线,可能会返回404错误或其他异常。

这种方法适用于HTTP绑定的服务,但不适用于如NetTcp等其他绑定方式的服务。

方案二:反射生成通用检测代理

另一个方法是利用反射技术动态生成通用的ChannelProxy,并尝试调用特定的方法来检测服务的状态。这种方法需要谨慎选择检测方法,通常选择不会影响业务逻辑的查询级别方法。

以下是一个使用反射技术检测WCF服务状态的示例:

private bool IsLive(string assemblyName, string apiServiceFullName, string endpointName, string testMethodName){    var basePath = AppDomain.CurrentDomain.BaseDirectory;    Type apiType = null;    var asm = Assembly.LoadFrom(basePath + "/services/" + assemblyPath);    apiType = asm.GetType(apiServiceFullName);    var channelType = typeof(ChannelFactory<>).MakeGenericType(apiType);        try    {        FuncExtension.TryDo(() =>        {            var channel = Activator.CreateInstance(channelType, endpointName);            Type[] types = new Type[0];            var createChannelMethod = channelType.GetMethod("CreateChannel", types);            var proxy = createChannelMethod.Invoke(channel, null);                        try            {                var testMethod = apiType.GetMethod(testMethodName);                var parameterInfos = testMethod.GetParameters();                List parameters = new List();                                foreach (var parameterInfo in parameterInfos)                {                    var defaultValue = parameterInfo.ParameterType.IsValueType                        ? Activator.CreateInstance(parameterInfo.ParameterType)                        : null;                    parameters.Add(defaultValue);                }                                testMethod.Invoke(proxy, parameters.ToArray());            }            catch (Exception exc)            {                Logger.Error(string.Format("Try to connect wcf service error:{0}, ExceptionType:{1}", endpointName, exc.GetType()), GetType(), exc);                throw;            }            finally            {                try                {                    (proxy as ICommunicationObject).Close();                }                catch                {                    (proxy as ICommunicationObject).Abort();                }            }        }, 3);        return true;    }    catch (Exception exc)    {        PrintWholeException(exc);        return !IsHttpOrSocketException(exc);    }}private void PrintWholeException(Exception exc){    Logger.Error(exc.GetType().ToString(), GetType(), exc);    if (exc.InnerException != null)    {        PrintWholeException(exc.InnerException);    }}private bool IsHttpOrSocketException(Exception exc){    if (exc is EndpointNotFoundException || exc is SocketException)    {        return true;    }    else    {        if (exc.InnerException != null)        {            return IsHttpOrSocketException(exc.InnerException);        }    }    return false;}

工作原理说明

  • 加载服务assembly:从指定路径加载包含目标WCF服务的assembly,获取服务接口类型。
  • 反射生成ChannelFactory:使用反射技术生成对应的ChannelFactory实例。
  • 创建通道代理:通过反射调用CreateChannel方法,生成通道代理。
  • 调用检测方法:调用用户定义的检测方法,传递必要的参数。
  • 异常处理:捕捉可能发生的异常,判断是否为HTTP或Socket相关异常,决定是否视为服务未在线。
  • 配置说明

    要实现上述检测逻辑,需要在配置文件中配置以下信息:

    • 服务接口协定:目标WCF服务的接口定义,通常放在配置文件中或使用MVC的路由配置。
    • 端点配置:目标WCF服务的端点配置,包括地址、绑定信息等。
    • 测试方法:在接口中定义一个用于检测服务状态的方法,通常没有副作用。
    • 程序集路径:确保反射加载所需的assembly,建议将其复制到项目根目录或指定路径。

    这种方法的核心优势在于其通用性,通过动态反射可以支持多种绑定方式的WCF服务,只需配置相应的接口和检测方法即可无缝集成。

    转载地址:http://hxdyz.baihongyu.com/

    你可能感兴趣的文章
    php7,从phpExcel升级到PhpSpreadsheet
    查看>>
    PHP8.1 + ThinkPHP实战指南:高效构建现代化网站的六大技巧
    查看>>
    PHP8中match新语句的操作方法
    查看>>
    PHP:第一章——PHP中常量和预定义常量
    查看>>
    PHP:第一章——PHP中的位运算
    查看>>
    phpcms
    查看>>
    phpcms 2008 product.php pagesize参数代码注射漏洞
    查看>>
    phpcms V9 自定义添加 全局变量{DIY_PATH}方法
    查看>>
    Redis五种核心数据结构的基本使用与应用场景
    查看>>
    Redis五种数据结构简介
    查看>>
    PHPCMS多文件上传和上传数量限制
    查看>>
    phpEnv的PHP集成环境
    查看>>
    PHPExcel一些基本设置总结
    查看>>
    phpexcel中文手册
    查看>>
    PHPExcel导入导出 若在thinkPHP3.2中使用(无论实例还是静态调用(如new classname或classname::function)都必须加反斜杠,因3.2就命名空间,如/c...
    查看>>
    phpMailer发送邮件
    查看>>
    PHPMailer发送邮件
    查看>>
    phpmailer发送邮件,可以带附件
    查看>>
    phpmyadmin 安装
    查看>>
    phpmyadmin导出数据库出现Fatal error: Cannot 'break' 2 levels in D:\phpstudy\WWW\phpMyAdmin
    查看>>