Welcome

首页 / 软件开发 / 数据结构与算法 / enode框架入门:框架的总体目标

enode框架入门:框架的总体目标2013-11-26 博客园 netfocus本文想介绍一下enode框架要实现的目标以及部分实现分析思路剖析。总体来说enode框架是一个基于cqrs 架构和消息驱动的应用开发框架。在说实现思路之前,我们先看一下enode框架希望实现的一些目标吧!

框架总体目标

高吞吐量(High Throughput)、低延迟(Low Latency)、高可用性(High Availability);

需要能充分利用CPU,即要允许方便配置需要使用的并行处理线程数,以提高单台机器的command处理能力 ;

支持command的同步和异步处理,同步处理时要允许客户端捕获异常,异步处理时要允许客户端设置回调函 数;

应用编程模型要统一,框架api要简单、好用、一致、好理解;

能让开发人员只关注业务,不用关心数据哪里来,以及如何保存,也不用关心并发、重试、超时等技术相 关的问题;

基于消息驱动的架构,那消息投递方面,要能做到:至少投递一次(即如果宕机了消息也不能丢)、且能 做到最多投递一次,因为有时我们无法做到消息的等幂处理;

要足够可扩展,框架中每个组件都要允许用户自定义并替换掉,包括IOC容器;

因为是CQRS架构,那必须要确保单个聚合根的事件的持久化顺序与分发给查询端的顺序要完全一致,否则 会出现严重的数据不一致的问题;

实现高吞吐量、低延迟、高可用的思路分析

概念:

吞吐量是指系统每秒可以处理的请求数 ;延迟是指系统在处理一个请求时的延迟;一般来说,一个系统的性能受到这两个条件的约束,缺一不可。比 如,我的系统可以顶得住一百万的并发,但是系统的延迟是2分钟以上,那么,这个一百万的负载毫无意义。 系统延迟很短,但是吞吐量很低,同样没有意义。所以,一个好的系统的性能测试必然受到这两个条件的同时 作用。有经验的朋友一定知道,这两个东西的一些关系:Throughput越大,Latency会越差。因为请求量过大 ,系统太繁忙,所以响应速度自然会低。Latency越好,能支持的Throughput就会越高。因为Latency短说明处 理速度快,性能高,于是就可以处理更多的请求。所以,可以看出,最根本的,我们是要尽量缩短单次请求处 理的时间。另外,可用性是指系统的平均无故障时间,系统的可用性越高,平均无故障时间越长。如果你的系 统能保持一年365天都能7*24全天候正常运行,那说明你的系统可用性非常高。

总体思路:

要 实现高可用,要怎么办?简单的办法就是主备模式,即一份站点同时运行在主备服务器上,主服务器如果正常 ,那所有请求都由主服务器处理,当主服务器挂了,那自动切换到备服务器;这种方式能确保高可用;甚至我 们还能设置多台备的服务器增加可用性;但是主备模式解决不了高吞吐量的问题,因为一台机器能处理的请求 数总是有限的,那怎么办呢?我觉得就需要让我们的系统支持集群部署了,也就是说,不是只有一台机器在服 务,而是同时有很多台机器在服务,这些同时服务的机器称为一个集群。而且为了能让集群中的服务器的负载 能平衡,为了尽量避免某台服务器很忙,其他服务器很空的情况,我们还需要负载均衡技术。当然,真正的高 可用同样意味着不能有单点故障问题,就是不能因为集群中的一个点挂了导致整个集群挂掉,所以我们要杜绝 所有的数据都要经过某个点的设计;相反,要做到每个点都能横向扩展,web应用站点(enode框架支持)、内 存缓存(memcached,redis都支持)、持久化(mongodb支持),都要能支持集群与负载均衡。好,整个系统所 有层次都支持集群+负载均衡解决了高吞吐高可用无单点的问题,但并没有解决低延迟的问题,那怎么办呢? 如何才能尽量快的处理一个用户请求呢?我觉得关键是三个方面:In Memory+尽量快的IO+无阻赛,也就是内 存模式加很快的数据持久化加无阻塞的编程模型。

In Memory

in memory是什么意思呢?在 enode框架中,主要的体现是,当我们要获取领域聚合根对象然后进行一些业务逻辑操作时,是从内存获取, 而不是从数据库。这样的好处就是快。那这样做要面临的一些问题,如内存不够怎么办?用分布式缓存,如 memcached, redis这样的成熟基于key-value模式的nosql产品。redis服务器挂了怎么办?没关系,我们可以 让框架自动处理,即当发现内存缓存中不存在时,自动在从eventstore取,就是取出当前聚合根的所有事件, 然后使用事件溯源(event sourcing,简称ES)的机制还原聚合根,然后尝试更新到缓存,然后返回给用户。 这样就解决了缓存挂了的问题,当redis缓存服务器重启后,又能继续从缓存中取聚合根了;实际上,我们也 要根据情况进行分布式集群部署redis服务器,这样一方面是为了能将数据sharding,另一方面能提高缓存的 可用性,因为不会因为一台redis缓存服务器挂了导致整个系统所有的缓存数据都丢失了。另外,你可能会奇 怪,redis缓存服务器里的数据哪里来呢?同样利用ES模式,因为我们在eventstore中存储了所有聚合根的所 有的事件,所以我们就能在redis缓存服务器启动时,对所有需要放在缓存中的聚合根根据ES模式来得到。