一、Thrift是什么?
关于Thrift的基本介绍,参看张善友的文章Trift简介。
二、为什么使用微服务?
在公司的高速发展过程中,随着业务的增长,子系统越来越多。各系统间又不同程度的在某些逻辑上出现重合的场景。为了高效率的开发,必然出现到重用这些逻辑的实现代码的情况,通常的做法是直接引用相关的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