關於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