• Thrift搭建分布式微服务(四)


          第一篇 《连接配置》

        第二篇 《连接池》

        第三篇 《标准通信》

        

    第四篇 快速暴露接口

        之前的文章,我们介绍了如何使用连接池管理Thrift节点,以及使用Thrift搭建微服务用到的标准输入输出。这一篇,我将介绍如何快速暴露服务接口,并对服务端进行错误处理。

        从代码图上看,开发者在使用Thrift.Utility搭建微服务时,两个类围绕着标准输入输出,是最常用的两个类,ThriftClient上一篇已经讲过,用于客户端,与服务端建立连接,并访问服务端接口,返回值。ThriftService用于服务端,用来暴露服务接口,我们看一下ThriftService.cs:    

     1     public abstract class ThriftService
     2     {
     3         protected virtual string Excute<Q>(StandRequest<Q> request, Func<StandRequest<Q>, string> func)
     4         {
     5             if (request.IsValid())
     6             {
     7                 try
     8                 {
     9                     string result = string.Empty;
    10                     if (func != null)
    11                     {
    12                         result = func(request);
    13                     }
    14                     StandResponse<string> response = new StandResponse<string>
    15                     {
    16                         Code = "0",
    17                         Desc = "SUCCESS",
    18                         Data = result
    19                     };
    20                     return SerializeHelper.JsonSerialize2(response);
    21                 }
    22                 catch (Exception ex)
    23                 {
    24                     CatchException(ex);
    25                     StandResponse<string> response = new StandResponse<string>
    26                     {
    27                         Code = "-2",
    28                         Desc = "服务端异常",
    29                         Data = string.Empty
    30                     };
    31                     return SerializeHelper.JsonSerialize2(response);
    32                 }
    33             }
    34             StandResponse<string> res = new StandResponse<string>
    35             {
    36                 Code = "-1",
    37                 Desc = "请求数据异常",
    38                 Data = string.Empty
    39             };
    40             return SerializeHelper.JsonSerialize2(res);
    41         }
    42 
    43         /// <summary>
    44         /// 异常处理
    45         /// </summary>
    46         /// <param name="ex"></param>
    47         protected abstract void CatchException(Exception ex);
    48     }

    这个类做了两件事,第一件事就是提供了供服务端暴露接口时使用的方法Excute(StandRequest<Q> request, Func<StandRequest<Q>, string> func),只需将得到的请求参数反序列化成StandRequest<Q>,传入Excute,Excute将返回序列化好的响应。第二件事就是,在Excute里提供了错误处理机制,避免开发者进行重复的劳动,开发者只需要重写CatchException方法。

        先看一下传统的调用一个本地的方法是怎么做的:

    1 List<BrandInfo> brans = ProductService.GetBrandByVendorSysNo(32);

    再看看用Thrift.Utility如何调用远端的服务:

    1 using (var tc = new ThriftClient<ProductService.Client>("ProductService"))
    2 {
    3     List<BrandInfo> brands = tc.Invoke<int, List<BrandInfo>>("GetBrandByVendorSysNo", 32);
    4 }

    很简洁吧,如何做到的呢?

     1     public class ProductServiceImpl :ThriftService, ProductService.Iface
     2     {
     3         public string GetBrandByVendorSysNo(string request)
     4         {
     5             var req = SerializationUtility.JsonDeserialize2<StandRequest<int>>(request);
     6             return Excute(req, (arg) =>
     7             {
     8                 //调用Service,这是没有使用Thrift之前的方法,通过string GetBrandByVendorSysNo(string request)将其暴露给客户端调用,就这4、5行代码就可以暴露一个服务接口。                   
     9                 List<BrandInfo> brans = ProductService.GetBrandByVendorSysNo(req.Data);
    10                 return SerializationUtility.JsonSerialize2(brans);
    11             });
    12         }
    14 15 protected override void CatchException(Exception ex) //开发者自己实现服务端错误处理 16 { 17 if (ex is BusinessException) 18 { 19 20 } 21 else 22 { 23 24 } 25 } 26 }

    使用本框架,暴露服务端接口就是这么简单。再看看客户端的配置:

    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <ThriftConfig>
    3   <MonitorType>Demo.RPCClient.ConnectionPoolMonitor,Demo.RPCClient</MonitorType>
    4   <ServiceArray>
    5     <Service Name="ProductService" IP="127.0.0.1" Port="7911" MaxActive="100" MaxIdle="20" MinIdle="10" WaitingTimeout="1000"/>
    6     <Service Name="SOService" IP="127.0.0.1" Port="7912" MaxActive="100" MaxIdle="20" MinIdle="10" WaitingTimeout="1000"/>
    7   </ServiceArray>
    8 </ThriftConfig>

    客户端自定义模拟器示例:

     1     public class ConnectionPoolMonitor:IThriftFactoryMonitor
     2     {
     3         public void Monitor(List<Tuple<string, int, int>> tuples)
     4         {
     5             foreach (var t in tuples)
     6             {
     7                 Console.WriteLine(string.Format("自定义{0}连接池,空闲连接数量:{1},激活连接数量:{2}", t.Item1, t.Item2, t.Item3));
     8             }
     9         }
    10 
    11         public void TimeoutNotify(string serviceName, int timeOut)
    12         {
    13             Console.WriteLine(string.Format("自定义{0}连接池等待连接超时{1}", serviceName, timeOut));
    14         }
    15     }

        Demo的代码没有提供给大家,感兴趣的可以照着示例自己写一个。

        到此整个系列就完结了,之所以写这个系列的文章,是希望和园友们进行交流讨论,如果代码中有什么缺点或没考虑到的地方,还希望园友们能提出来,加以改善,让这个框架更完美。

    Thrift微服务代码下载Thrift.Utility

  • 相关阅读:
    ent 基本使用十二 字段
    ent 基本使用十一 sql.DB 集成
    ent 基本使用十 数据库迁移
    ent 基本使用九 代码生成
    ent 基本使用八 索引
    ent 基本使用七 Config
    ent 基本使用六 Mixin
    ent 基本使用五 schema介绍
    ent 基本使用四 图遍历查询
    ent 基本使用 三 边(关系处理)
  • 原文地址:https://www.cnblogs.com/DKSL/p/Thrift_Utiliry4.html
Copyright © 2020-2023  润新知