關於Thrift的基本介紹,參看張善友的文章Thrift簡介。
在公司的高速發展過程中,隨著業務的增長,子系統越來越多。各系統間又不同程度的在某些邏輯上出現重合的場景。為了高效率的開發,必然出現到重用這些邏輯的實現代碼的情況,通常的做法是直接引用相關的DLL。各子系統分別是不同的團隊完成開發,直接引用DLL可能導致潛在的命名空間重復問題,以及因為方法的使用場景不明確給方法調用造成混亂等問題。另一種解決方案,就是部署統一的接口,對底層數據庫的訪問以及一些共同的邏輯進行統一封裝。這種解決方案的實現要麼考慮SOA,要麼微服務。考慮到成本,微服務要更方便實施一些。
Thrift采用Socket進行通信,使用Thrift搭建微服務,那它應該能夠與多個IP或者端口建立TCP連接。怎樣對這些連接進行統一的管理,並且能夠方便的使用這些連接?使用XML配置連接,使用連接池管理TCP Socket連接。
Thrift天然支持的數據結構對於.net可能太夠用,對於復雜的數據結構,怎樣使用它們通信?考慮所有的通信傳輸數據都使用Json字符串。
服務端發生異常如何通知客戶端?
身份驗證問題。
如何監控連接池運行狀態?
Thrift要建立TCP Socket的連接,首先要有IP地址和端口。因為用使用連接池來管理連接,就必須設置它的最大激活連接數、最大空閒連接數、最小空閒連接數。當激活的連接數達到了最大連接數,會使獲取Socket連接的請求處於等待狀態,這時需要設置一個最大等待時間,當等待超時,應有相應的動作,是去記日志還是通知連接池管理者修改連接池配置,這由開發者自己去實現。
1 [Serializable]
2 public class ServiceConfig
3 {
4 [XmlAttribute]
5 public string Name { get; set; }
6
7 [XmlAttribute]
8 public string IP { get; set; }
9
10 [XmlAttribute]
11 public int Port { get; set; }
12
13 [XmlAttribute]
14 public int MaxActive { get; set; }
15
16 [XmlAttribute]
17 public int MaxIdle { get; set; }
18
19 [XmlAttribute]
20 public int MinIdle { get; set; }
21
22 /// <summary>
23 /// 連接池等待連接時間
24 /// 單位毫秒
25 /// 超時記日志還是通知誰更改連接池配置
26 /// </summary>
27 [XmlElement, DefaultValue(1000)]
28 public int WaitingTimeout { get; set; }
29 }
很顯然,一個節點的服務不能叫做微服務,所以要對這些連接節點進行管理還需要一個配置:
1 [Serializable]
2 public class ThriftConfig
3 {
4 /// <summary>
5 /// 監視器類型
6 /// 用於監視連接池運行狀態
7 /// 繼承自ITriftFactoryMonitor類
8 /// </summary>
9 [XmlElement]
10 public string MonitorType { get; set; }
11
12 [XmlArrayItem("Service")]
13 public List<ServiceConfig> ServiceArray { get; set; }
14 }
如何讀取這些配置,使這些配置為連接池所用?
1 public static List<ServiceConfig> GetServiceConfigs()
2 {
3 List<ServiceConfig> services = new List<ServiceConfig>(ThriftConfig.ServiceArray.Count);
4 foreach(var sc in ThriftConfig.ServiceArray)
5 {
6 if (!services.Exists(service => service.Name.ToUpper() == sc.Name.ToUpper()))
7 {
8 //IP驗證
9 if (IsIPV4Address(sc.IP))
10 {
11 services.Add(sc);
12 }
13 else
14 {
15 throw new ThriftException(string.Format("The Service Config Named \"{0}\",Which's IP({1}) Is Not Valid!", sc.Name, sc.IP));
16 }
17 }
18 else
19 {
20 throw new ThriftException(string.Format("There Is A Service Config Named \"{0}\",Please Check Service Config File!", sc.Name));
21 }
22 }
23 if (services.Count==0)
24 {
25 throw new ThriftException("There Is No Specific Service!");
26 }
27 return services;
28 }
29
30 private static ThriftConfig LoadThriftConfig()
31 {
32 string path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, ThriftConfigFilePath);
33 if (File.Exists(path))
34 {
35 return SerializeHelper.LoadFromXml<ThriftConfig>(path);
36 }
37 throw new ThriftException(string.Format("Not Found Thrift Config File \"{0}\"", path));
38 }
准備工作做好了,下一篇,將講解如何使用這些配置來建立連接池。
Thrift微服務代碼下載Thrift.Utility