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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM