小时候老是跟妈妈着去上班。妈妈是儿科医生。有一天来了一个妈妈带着他的宝宝挂了妈妈的专家号。宝宝长得很可爱,可是脸上没有任何表情,脑壳很大,四肢和刚出生的宝宝同样大。妈妈抬起宝宝的四肢,一放手它又耷拉回去。妈妈说话声音很沉重,说我直接给你开个证实吧,你能够再要一个孩子。那个妈妈一句话都没说,只是坐在那里抱着她的宝宝。这个妈妈在化工厂工做,每天和染料打交道。这已经不是她的第一个宝宝了,每一个宝宝命运都差很少。这个妈妈的绝望和医学无关。因此高考的时候,怎么都不愿听妈妈的。本身报了计算机。妈妈知道后让我去找老师改回来。我走到半路给妈妈买了件衣服就回来了。妈妈虽然仍是很想让我学医,可是看到我买的衣服显然很高兴,也明白她是拗不过个人,只好做罢。php
这个选型主要决定于系统复杂度。先回顾一下。前端
1>单一应用架构:对于一个流量很小的网站来讲,只需一个应用,将全部功能都部署在一块儿,以减小部署节点和成本。以前在上家公司作过一个微信公众号的开发就是基于这种架构,我和一个大牛的前端架构师两我的就是一个项目,仍是挺happy的。可是这种架构其实用java的成本有点高,用PHP更快。因此我本身接了个私活作个相似携程+如家的网站用的就是php。java
2>垂直应用架构:访问量再大一点,能够将应用拆成互不相干的几个应用,以提高效率。8年前刚进人人网的时候用的就是这个架构。由于是社交网站,被拆分红了SNS,UGC,各个游戏等子模块。redis
3>分布式服务架构:垂直应用多了,交互不可避免,将核心业务抽取出来做为独立的服务,造成稳定的服务中心。大概从11年起,人人网逐渐采用这种架构。随之而来的是采用一些技术,记得最初也采用过RMI的,都是内部调用,防火墙也应该不是问题。可是后来hession和thrift开始流行,咱们又进行了这方面的尝试。zookeeper用做注册中心,主要是配置管理方面。算法
4>流动计算架构:当服务愈来愈多,容量的评估,小服务资源的浪费等问题逐渐显现,此时须要增长一个调度中心基于访问压力实时管理集群容量,资源调度和提升集群利用率。spring
Dubbo是Alibaba开源的分布式服务框架,按照分层来架构,使各个层之间解耦合。在咱们项目中,做为服务层和业务层的桥梁来使用。Dubbo层能够用servlet容器启动,也能够直接用main函数直接加载ApplicationContext。总之,dubbo是依赖于spring来管理的。Dubbo框架设计共划分了10层。其中服务接口层,配置层,服务代理层是开发须要自行写入的,用法自行百度。数据库
下面说一下服务注册层。它以服务URL为中心,扩展接口为RegistryFactory,Registry和RegistryService。打开RegistryFactory的源码能够看到,这是一个SPI的,核心工做就是取得其注册的信息。内部实现类是DubboRegistryFactory。做用就是根据url从一个本地的concurrenthashmap中取出其注册信息,若是注册信息不存在,则建立一个。同时将此注册目录加入集群。这种concurrenthashmap的东西要返回视图,返回的通常都是一个unmodify的拷贝。Dubbo里为了减小对apache的依赖,用的是java.util里的Collections.unmodifiableCollection。apache
集群层。这一层是上面提到的流动架构的体现。封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster,Directory,Router和LoadBalance。从SPI的配置文件来看,支持4种经常使用的负载均衡缓存
random=com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance roundrobin=com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance leastactive=com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance consistenthash=com.alibaba.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
具体类里基本都是算法的实现,能够不用看了。Cluster支持的算法以下:微信
mock=com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper failover=com.alibaba.dubbo.rpc.cluster.support.FailoverCluster failfast=com.alibaba.dubbo.rpc.cluster.support.FailfastCluster failsafe=com.alibaba.dubbo.rpc.cluster.support.FailsafeCluster failback=com.alibaba.dubbo.rpc.cluster.support.FailbackCluster forking=com.alibaba.dubbo.rpc.cluster.support.ForkingCluster available=com.alibaba.dubbo.rpc.cluster.support.AvailableCluster mergeable=com.alibaba.dubbo.rpc.cluster.support.MergeableCluster broadcast=com.alibaba.dubbo.rpc.cluster.support.BroadcastCluster
监控层:RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory, Monitor和MonitorService。实现上和注册层的实现是同样的。
远程调用层:封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol,Invoker和Exporter。Protocal是服务域,它是Invoker暴露和引用的主功能入口,负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其余模型转换成它。它表明一个可执行体,可向它发起invoker调用,它有多是一个本地实现,也多是一个远程的实现,也多是一个集群实现。相信了解过java动态代理的话,这个不难理解。
信息交换层:封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger,ExchangeChannel,ExchangeClient和ExchangeServer。
网络传输层:抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel,Transporter,Client,Server和Codec。
数据序列化层:可复用的一些工具,扩展接口为Serialization,ObjectInput,ObjectOutput和ThreadPool。
能够以dubbo配置项的解析为入口跟进源码。在dubbo jar包下META-INF里面的spring.handlers里,有自定义的spring命名空间处理器,能够找到对应的java类。dubbo的引入不可避免的带来IO,像我们写代码的,这儿压缩几个字节,那儿解开一个循环,这些代码优化可能轻易就被低效的IO所抵消。IO操做比在内存中进行数据处理所需的时间通常长20倍。前段时间用CAT作性能监控就发现,若是没有dubbo层大概几ms的操做,引入dubbo执行时间正常都在几百ms。因此SOA要谨慎。要懂一些底层原理的话,其实架构的选择就能少些纠结,看各类框架也能立刻就明白。网友问我在读什么书,其实如今不多有时间读,开放平台项目进入联调阶段了,还有不少细节能够优化的地方,仍是挺忙的。之因此看到个人文章乱序严重也是由于我是用特别零散的时间来写的。可是前段时间不是看了<netty in action>嘛,看这本书就不得再也不看看<java nio>作一下对比,看了<java nio>呢,里面做者又推荐读一下《操做系统第六版》,话说我大学也是计算机的,可是这本书仍是须要从新看一遍的。每本书做者都会引入一些相关的好书,因此个人书单永远空不了。
dubbo底层不论是用mina也好,netty也好,IO原理都是同样的。好比和底层相关的,以前我也提到我曾经本身分析过图片的二进制流来获取图片翻转信息。在这个过程当中我了解到和底层操做系统相关的两个标准,Intel标准和摩托罗拉标准。分别对应两种字节顺序:大端字节顺序和小端字节顺序。了解这个对于nio的缓冲区也有帮助。而通道不是分为单工,双工,半双工嘛。面向流的socket确定是双工的,因此流在网络中请求和响应的读写操做才能够同时进行。而像文件IO这样的,读写确定是分离的,单工进行的。
上周有人问我咱们的项目使用缓存和数据库就能解决问题,为啥要开发一个搜索引擎,考虑问题的角度不是应该放在数据分析上吗?我表示赞成他的观点,由于我本身没组织好语言说服不了人家的时候我都是这个态度。实际上,首先说咱们已经分析出来了,瓶颈就在缓存上了。缓存采用memcached也是缓存,redis也是缓存。实际上solr也是缓存啊!这种缓存是基于多维数据结构的获取,合适咱们的项目也合适不少列表带维度的项目。我认为之后是颇有前景的。而solr或者说es或者说dubbo或者memcached或者redis面临的问题都是同样的,性能嘛,而性能最大的消耗点就是io。咱们项目用的dubbo+缓存。是两次跨网络的io。dubbo解决的是服务复用的问题,缓存解决的是空间换时间的问题,搜索引擎能够作为一个独立的服务一次io同时解决这两个问题,我为啥让人家明白不了呢