网上看到某牛人写的架构方面的文章,感叹技术的博大呀

    任何应用都需要与资源打交道,这个资源可能是文件、内存、网络、数据库、web服务等。特别是系统的可伸缩性和性能上,一个系统的可伸缩性很大程度上取决于该系统资源管理的可伸缩性。资源的获取是资源生命周期的起点,因此在此阶段的优化和配置对系统性能、可用性、稳定性、可伸缩性的影响是至关重要的。资源的获取要解决 这么两个问题:怎么找到资源,何时获取资源。
    资源的超找可以通过lookup模式,所谓lookup模式就是引入一个查找服务作为中介,让资源使用者可以 找到并使用资源提供者提供的资源。这方面一个显然的例子就是JNDI,我们通过JNDI查找EJB、数据库连接池等,另一个例子就是RMI,客户端通过命名服务查找到远程对象。查找服务提供查询语言,也提供接口让服务注册到它的容器内。
    何时获取资源?根据时机的不同可以分为预先获取模式和延迟获取模式。如果对系统的可用性和运行时性能要求比较高,那么可能你会预先加载或者分配所要用到的资源,通过一个资源提供者的代理对象拦截对资源的请求,返回预先加载或者分配的资源,从而提高系统性能。这方面的例子就是 memcached,memcached启动时预先分配内存来提高性能(相应的带来的是内存的不能有效利用)。线程池、数据库连接池也是预先获取模式的例子,通过预先创建的线程或者数据库连接,来提高系统的整体性能。反之,延迟获取模式就是尽可能到使用资源的最后一刻才去获取资源,一开始返回的只是一个资源的代理对象,真正使用到资源的时候由这个代理对象去加载实际的资源。延迟获取模式的例子也很多,例如 Hibernate的延迟加载,延迟加载的对象其实是一个代理类(通过java动态代理或者cglib增强),只有真正用到的时候才去数据库获取实际的数 据。函数式编程中的延时求值也是延迟获取模式的例子,没有求值前只是个promise,求值到的时候才force执行。Singleton模式下的单例也常常做延迟初始化,这是延迟获取模式的特化。

    如果资源的大小很大、极大或者是未知尺寸,预先获取会导致系统速度的缓慢甚至耗尽系统资源,延迟获取在获取的时候也可能时间过长难以忍受或者耗尽系统资源,两者都不适合,解决办法就是分步获取,这就是所谓部分获取模式。将资源的获取分为两步或者多步,每一步获取一定数目的资源,每一步获取资源也可以采用预先或者延迟的策略。这样的例子如socket读数据到缓冲区,一次可能只读一部分数据到缓冲区,分步才读完。再比如web页面一棵树的展 现,一开始可能只是显示部分节点,在需要查看一些节点的时候才会通过ajax加载和展开它们的子结点乃至深层子结点。

    MQ在分布式系统中扮演着重要角色,异步的消息通信全要靠它,而异步通信正是提高系统伸缩性的不二良方。说说我认为的一个优秀的MQ产品需要具备的特征。

    首先显然是高可用性,我们当然希望MQ能支撑7x24小时应用,而不是三天两头当机,我们要追求的是99.9%的可靠服务时间。要做到高可用性,显然我们需要做MQ的集群,一台当了,不影响整个集群的服务能力,这里涉及到告警、流控、消息的负载均衡、数据库的使用、测试的完备程度等等。

    其次是消息存储的高可靠性。我们要保证100%不丢消息。要做到消息存储的高可靠性,不仅仅是MQ的责任,更涉及到硬件、操作系统、语言平台和数据库的一整套方案。许多号称可靠存储的MQ产品其实都不可靠,要知道,硬件错误是常态,如果在硬件错误的情况下还能保证消息的可靠存储这才是难题。这里可能需要用到特殊的存储硬件,特殊的数据库,分布式的数据存储,数据库的分库分表和同步等等。你要考虑消息存储在哪里,是文件系统,还是数据库,是本地文件,还是分布式文件,是搞主辅备份呢还是多主机写入等等。
    
    第三是高可扩展性,MQ集群能很好地支持水平扩展,这就要求我们的节点之间最好不要有通信和数据同步。

    第四是性能,性能是实现高可用性的前提,很难想象单机性能极差的MQ组成的集群能在高负载下幸免于难。性能因素跟采用的平台、语言、操作系统、代码质量、数据库、网络息息相关。MQ产品的核心其实是消息的存储,在保证存储安全的前提下如何保证和提高消息入队的效率是性能的关键因素。这里需要开发人员建立起性能观念,不需要你对一行行代码斤斤计较,但是你需要知道这样做会造成什么后果,有没有更好更快的方式,你怎么证明它更好更快。软件实现的性能是一方面,另一方面就是平台相关了,因为MQ本质上是IO密集型的系统,瓶颈在IO,如何优化网络IO、文件IO这需要专门的知识。性能另一个相关因素是消息的调度上,引入消息顺序和消息优先级,允许消息的延迟发送,都将增大消息发送调度的复杂性,如何保证高负载下的调度也是要特别注意的地方。

   

   第五,高可配置性和监控工具的完整,这是一个MQ产品容易忽略的地方。异步通信造成了查找问题的难度,不像同步调用那样有相对明确的时序关系。因此查找异步通信的异常是很困难的,这就需要MQ提供方便的DEBUG工具,查找分析日志的工具,查看消息生命周期的工具,查看系统间依赖关系的工具等等。可定制也是MQ产品非常重要的一方面,可方便地配置各类参数并在集群中同步,并且可动态调整各类参数,这将大大降低维护难度。 

posted @ 2009-10-20 10:18  echozhjun  阅读(140)  评论(0)    收藏  举报