Thrift搭建分布式微服务(四)
第一篇 《连接配置》
第二篇 《连接池》
第三篇 《标准通信》
第四篇 快速暴露接口
之前的文章,我们介绍了如何使用连接池管理Thrift节点,以及使用Thrift搭建微服务用到的标准输入输出。这一篇,我将介绍如何快速暴露服务接口,并对服务端进行错误处理。
从代码图上看,开发者在使用Thrift.Utility搭建微服务时,两个类围绕着标准输入输出,是最常用的两个类,ThriftClient上一篇已经讲过,用于客户端,与服务端建立连接,并访问服务端接口,返回值。ThriftService用于服务端,用来暴露服务接口,我们看一下ThriftService.cs:
 1     public abstract class ThriftService
 2     {
 3         protected virtual string Excute(StandRequest request, Func, 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 response = new StandResponse
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 response = new StandResponse
26                     {
27                         Code = "-2",
28                         Desc = "服务端异常",
29                         Data = string.Empty
30                     };
31                     return SerializeHelper.JsonSerialize2(response);
32                 }
33             }
34             StandResponse res = new StandResponse
35             {
36                 Code = "-1",
37                 Desc = "请求数据异常",
38                 Data = string.Empty
39             };
40             return SerializeHelper.JsonSerialize2(res);
41         }
42 
43         /// 
44         /// 异常处理
45         ///  
46         /// 
47         protected abstract void CatchException(Exception ex);
48     }       
这个类做了两件事,第一件事就是提供了供服务端暴露接口时使用的方法Excute(StandRequest request, Func
,传入Excute,Excute将返回序列化好的响应。第二件事就是,在Excute里提供了错误处理机制,避免开发者进行重复的劳动,开发者只需要重写CatchException方法。
先看一下传统的调用一个本地的方法是怎么做的:
1 Listbrans = ProductService.GetBrandByVendorSysNo(32); 
再看看用Thrift.Utility如何调用远端的服务:
1 using (var tc = new ThriftClient("ProductService")) 2 { 3 List brands = tc.Invoke >("GetBrandByVendorSysNo", 32); 4 } 
很简洁吧,如何做到的呢?
 1     public class ProductServiceImpl :ThriftService, ProductService.Iface
 2     {
 3         public string GetBrandByVendorSysNo(string request)
 4         {
 5             var req = SerializationUtility.JsonDeserialize2>(request);
 6             return Excute(req, (arg) =>
 7             {
 8                 //调用Service,这是没有使用Thrift之前的方法,通过string GetBrandByVendorSysNo(string request)将其暴露给客户端调用,就这4、5行代码就可以暴露一个服务接口。                   
 9                 List 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" ?> 23 Demo.RPCClient.ConnectionPoolMonitor,Demo.RPCClient 45 86 7 
客户端自定义模拟器示例:
 1     public class ConnectionPoolMonitor:IThriftFactoryMonitor
 2     {
 3         public void Monitor(List> 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