高可用性有两个重点,一个是高可靠性,一个是高性能,而为了满足高性能又引入了架构本身的分布式和高扩展性,由于分布式架构的引入则形成我们常说的CAP理论和问题,即如何解决在高可靠和高性能下的事务和一致性问题,即使不能兼得,那么变通的方式是什么?
架构的高性能,首先要考虑的就是单点的高性能,不要认为引入了分布式和集群技术后就不关注单点本身的性能,很多时候我们的应用即使在相同的硬件环境下,只要我们对程序代码和数据库进行相应的优化,性能往往就能够得到大幅度的提升。因此不要用简单的资源不足和加集群等简单理由来为你本身架构和代码的坏味道买单。
由于在应用服务器层我们很容易通过硬件或软件技术来实现相应的集群部署,但是在数据库层往往却很难,因此对于去IOE架构下其所有的核心都将在数据库本身实现分布式,是引入完全分布式的数据库,还是对数据库进行水平和垂直切分,上面搭建DaaS数据库服务层。对于Mysql数据库,在淘宝corba后现在有了MyCat的开源分布式数据库版本,对于要搭建高性能分布式架构数据库的可以考虑采用。
数据库的垂直拆分的一个重点就是引入组件化开发和架构模式,在前面有篇文章里面刚好已经谈到了,例如引入淘宝的Dubbo分布式服务框架,来实现组件化和服务化架构模式。最终要做到的就是每一个业务组件都相当完全独立,组件的数据库和应用层都可以做到完全独立的管理和部署。组件之间只能通过暴露和注册到Dubbo上的服务进行交互。但是我们看到另外一个问题,即同一个组件本身在技术架构上也是分层的,如包括数据层,逻辑层,服务层和前端展现层。那么一个组件内部的前端和后端是否也需要使用Dubbo服务框架,通过分布式的服务进行暴露和管理,在这里我们的看法是完全没有必要的,一个组件内部本身的调用走内部服务和API接口调用接口,一方面是这种调用更多都是数据库表的CRUD操作并发量相当大,一方面是这类接口或服务本身也没有太大的重用和复用价值。
在引入领域服务的概念后,带来另外一个问题,即我们的服务层是否需要单独设计,开发和部署管理。在组件化开发思路里面要注意到,没有独立的服务组件,即具体暴露的服务接口本身是包含在业务组件里面的。即一个业务组件里面的接口或方法,通过服务代理机制发布为一个远程可以访问的服务。这种思路的核心本身也在于服务组件中的服务本身仅仅是一个代理,而最终的接口实现逻辑还是在原来的技术组件里面。这种设计和实现方法可以最大化的满足原有技术组件里面的业务逻辑和方法和复用。
那我们究竟是否需要独立的领域服务组件?根据实际的业务场景和需求可以看到,对于某些场景是需要考虑独立的领域服务组件的。即在处理具体的业务时候,我们需要调用多个业务组件中暴露的服务,并且对这些服务进行组合形成更加粗粒度的组合服务能力。同时这些组合服务能力本身又不应该归属于上层的任何一个业务组件内部,因此在这种情况下我们可以考虑剥离独立的服务层组件,这种服务层组件的核心目标就是提供独立的跨组件的领域服务能力,同时又相当独立。
在引入任何一个新技术或技术组件的时候,都要一开始就想清楚具体面对的业务场景或非功能性需求场景。要明白任何新技术的引入都会增加到这个系统的耦合性和复杂度。包括nosql数据库,分布式缓存,消息中间件,集群和心跳检测,全文检索等各种技术的引入都要一开始就想清楚场景和边界。只有边界分清楚了你才可能防止技术被乱用而无法管控。
任何分布式技术的引入可以看到,最让人头痛的问题就是这种分布式技术无法做到完全透明,做为一个黑盒子,对于上层业务和应用完全不用考虑底层究竟是否分布式了。这是一种理想情况,当前很多情况是分布式技术无法做到完全透明,导致很多架构约束抛给了上层业务应用开发。例如我们在引入类似corba分布式数据库后,对于常规sql语句中的关联,分组统计都不能很好的做到支持,同时对于分布式事务的支持仍然是一个很大的问题。这也是我们在选择引入分布式架构和技术务必慎重的原因。
分布式架构的引入另外一个重要思考就是,在一开始构建复杂的分布式架构时候就需要考虑到,这种架构我们在后期能否很好的进行自动化监控和运维。要知道这种架构模式下如果不能真正做到实时的自动化模式下的监控和运维本身就是一个噩梦。即需要在前面谈到的高可用性上面再增加一个架构在后期的高可运维性。包括最近我们看到APM比较活,重点也是在解决后期的监控和高可运维性问题。
任何架构的设计都一定是针对具体的业务场景,包括业务场景中的功能需求和非功能性需求,因此对于一个全新的架构设计务必不能简单的照搬互联网上的标准模型,而是应该真正根据自身的实际情况进行架构,要说服自己每一个技术点采用的必要性和具体原因。架构重点不是大而全,而是应该小而精;架构重点不是完全弹性和理想化,而是应该适度设计。因为我们看到太多由于架构本身过渡设计导致了整个业务应用设计,开发和运维上诸多的复杂度和困难。
引入DaaS和分布式数据库后重点要考虑组件怎么划分,数据库本身如何进行水平拆分和垂直拆分,组件之间如何进行服务化交互,包括服务化后引入的分布式事务问题如何解决;在引入缓存或分布式缓存机制后重点需要考虑的是缓存本身的同步和刷新机制;引入HA或集群机制后,最难的不是简单额负载均衡,而是如何通过完整的心跳和检测机制能够实时的监控中间件或数据库服务器的假死现象;在引入了消息中间件后需要考虑本身的异步机制带来的事务一致性问题,这些都需要在架构设计层面就考虑清楚。
一个架构师就犹如一个摩天大厦的总设计师,虽然大厦还没有建造完成,但是整个大厦的模型和运转机制已经深深的印在了心里。架构师在设计中的一个疏忽大意都可能导致业务应用这个大厦顷刻颠覆。一个优秀的架构师可能并不是顶尖的技术天才或狂热份子,但是他们一定是业务和技术,功能和非功能需求高度融合思考的人。