这边我推荐我看过的一本书 曾宪杰《大型网站系统与Java中间件实践》,对于后端的一些服务如何从单机到分布式讲解是很是深刻的,让你可以对后端各个层次的中间件框架有着进一步的理解。ios
在移动 APP 的开发过程当中,一般后端提供的接口须要如下功能的支持:git
通常的作法,使用 Nginx 作负载均衡,而后在每一个业务应用里作 API 接口的访问权限控制和用户鉴权,更优化一点的方式则是把后二者作成公共类库供全部业务调用。但从整体上来看,这三种特性都属于业务的公共需求,更可取的方式则是集成到一块儿做为一个服务,既能够动态地修改权限控制和鉴权机制,也能够减小每一个业务集成这些机制的成本。这种服务就是 API 网关,能够选择本身实现。也可使用开源软件实现,如 Kong 和 Netflix Zuul。API 网关通常架构以下图所示:github
可是以上方案的一个问题是因为全部 API 请求都要通过网关,它很容易成为系统的性能瓶颈。所以,能够采起的方案是:去掉 API 网关,让业务应用直接对接统一认证中心,在基础框架层面保证每一个 API 调用都须要先经过统一认证中心的认证,这里能够采起缓存认证结果的方式避免对统一认证中心产生过大的请求压力。web
统一认证中心,主要是对 APP 用户、内部用户、APP 等的认证服务,包括数据库
之因此须要统一认证中心,就是为了可以集中对这些全部APP都会用到的信息进行管理,也给全部应用提供统一的认证服务。尤为是在有不少业务须要共享用户数据的时候,构建一个统一认证中心是很是必要的。此外,经过统一认证中心构建移动APP的单点登陆也是水到渠成的事情:模仿 Web 的机制,将认证后的信息加密存储到本地存储中供多个 APP 使用。编程
目前不少大的在线 Web 网站都是有单点登陆系统的,通俗的来讲就是只须要一次用户登陆,就可以进入多个业务应用(权限能够不相同),很是方便用户的操做。而在移动互联网公司中,内部的各类管理、信息系统甚至外部应用一样也须要单点登陆系统。后端
目前,比较成熟的、用的最多的单点登陆系统应该是耶鲁大学开源的CAS, 能够基于 https://github.com/apereo/cas/tree/master/cas-server-webapp 来定制开发的。api
基本上,单点登陆的原理都相似下图所示:缓存
在 Java 后端应用中,一种读写配置比较通用的方式就是将配置文件写在 Propeties、YAML、HCON 等文件中,修改的时候只须要更新文件从新部署便可,能够作到不牵扯代码层面改动的目的。统一配置中心,则是基于这种方式之上的统一对全部业务或者基础后端服务的相关配置文件进行管理的统一服务, 具备如下特性:安全
百度开源的 Disconf 和携程的 Apollo 是能够在生产环境使用的方案,也能够根据本身的需求开发本身的配置中心,通常选择 Zookeeper 做为配置存储。
对于外部 API 调用或者客户端对后端 API 的访问,可使用 HTTP 协议或者 RESTful(固然也能够直接经过最原始的socket来调用)。但对于内部服务间的调用,通常都是经过 RPC 机制来调用的。目前主流的 RPC 协议有:
这些 RPC 协议各有优劣点,须要针对业务需求作出最好的选择。
这样,当你的系统服务在逐渐增多,RPC 调用链愈来愈复杂,不少状况下,须要不停的更新文档来维护这些调用关系。一个对这些服务进行管理的框架能够大大减小所以带来的繁琐的人力工做。
传统的 ESB(企业服务总线)本质就是一个服务治理方案,但 ESB 做为一种 proxy 的角色存在于 Client 和 Server 之间,全部请求都须要通过 ESB,使得 ESB 很容易成为性能瓶颈。所以,基于传统的ESB,更好的一种设计以下图所示:
如图,以配置中心为枢纽,调用关系只存在于 Client 和提供服务的 Server 之间,就避免了传统 ESB 的性能瓶颈问题。对于这种设计,ESB 应该支持的特性以下:
阿里开源的 Dubbo 则对以上作了很好的实现,也是目前不少公司都在使用的方案;当当网的扩展项目 Dubbox 则在 Dubbo 之上加入了一些新特性。目前,Dubbo 已经被阿里贡献给 Apache,处于incubating 状态。在运维监控方面,Dubbo 自己提供了简单的管理控制台 dubbo-admin 和监控中心 dubbo-monitor-simple。Github 上的 dubboclub/dubbokeeper 则是在其之上开发的更为强大的集管理与监控于一身的服务管理以及监控系统。
此外,Netflix 的 Eureka 也提供了服务注册发现的功能,其配合 Ribbon 能够实现服务的客户端软负载均衡,支持多种灵活的动态路由和负载均衡策略。
在不少业务中,定时调度是一个很是广泛的场景,好比定时去抓取数据、定时刷新订单的状态等。一般的作法就是针对各自的业务依赖 Linux 的 Cron 机制或者 Java 中的 Quartz。统一调度中心则是对全部的调度任务进行管理,这样可以统一对调度集群进行调优、扩展、任务管理等。Azkaban 和 Yahoo 的 Oozie 是 Hadoop 的流式工做管理引擎,也能够做为统一调度中心来使用。固然,你也可使用Cron或者Quartz来实现本身的统一调度中心。
对于 Java 的 Quartz 这里须要说明一下:这个 Quartz 须要和 Spring Quartz 区分,后者是 Spring 对 Quartz 框架的简单实现也是目前使用的最多的一种调度方式。但其并无作高可用集群的支持。而 Quartz 虽然有集群的支持,可是配置起来很是复杂。如今不少方案都是使用 Zookeeper 来实现 Spring Quartz 的分布式集群。
此外,当当网开源的 elastic-job 则在基础的分布式调度之上又加入了弹性资源利用等更为强大的功能。
日志是开发过程必不可少的东西。打印日志的时机、技巧是很能体现出工程师编码水平的。毕竟,日志是线上服务可以定位、排查异常最为直接的信息。
一般的,将日志分散在各个业务中很是不方便对问题的管理和排查。统一日志服务则使用单独的日志服务器记录日志,各个业务经过统一的日志框架将日志输出到日志服务器上。
能够经过实现 Log4j 或者 Logback 的 Appender 来实现统一日志框架,而后经过 RPC 调用将日志打印到日志服务器上。
业务应用分为:在线业务应用和内部业务应用。
业务应用基于后端的基础框架开发,针对 Java 后端来讲,应该有如下几个框架:
通常来讲,以上几个框架便可以完成一个后端应用的雏形。
缓存、数据库、搜索引擎、消息队列这四者都是应用依赖的后端基础服务,他们的性能直接影响到了应用的总体性能,有时候你代码写的再好也许就是由于这些服务致使应用性能没法提高上去。
无论是业务应用、依赖的后端服务仍是其余的各类服务,最终仍是要依赖于底层文件存储的。一般来讲,文件存储须要知足的特性有:可靠性、容灾性、稳定性,即要保证存储的数据不会轻易丢失,即便发生故障也可以有回滚方案,也要保证高可用。在底层能够采用传统的 RAID 做为解决方案,再上一层,目前 Hadoop 的 HDFS 则是最为广泛的分布式文件存储方案,固然还有 NFS、Samba 这种共享文件系统也提供了简单的分布式存储的特性。
此外,若是文件存储确实成为了应用的瓶颈或者必须提升文件存储的性能从而提高整个系统的性能时,那么最为直接和简单的作法就是抛弃传统机械硬盘,用 SSD 硬盘替代。像如今不少公司在解决业务性能问题的时候,最终的关键点每每就是 SSD。这也是用钱换取时间和人力成本最直接和最有效的方式。在数据库部分描述的 SSDB 就是对 LevelDB 封装以后,利用 SSD 硬盘的特性的一种高性能 KV 数据库。
至于 HDFS,若是要使用上面的数据,是须要经过 Hadoop 的。相似 xx on Yarn 的一些技术就是将非 Hadoop 技术跑在 HDFS 上的解决方案。
数据是最近几年很是火的一个领域。从《精益数据分析》到《增加黑客》,都是在强调数据的非凡做用。不少公司也都在经过数据推进产品设计、市场运营、研发等。这里须要说明的一点是,只有当你的数据规模真的到了单机没法处理的规模才应该上大数据相关技术,千万不要为了大数据而大数据。不少状况下使用单机程序 +MySQL 就能解决的问题非得上 Hadoop 即浪费时间又浪费人力。
这里须要补充一点的是,对于不少公司,尤为是离线业务并无那么密集的公司,在不少状况下大数据集群的资源是被浪费的。所以诞了 xx on Yarn 一系列技术让非 Hadoop 系的技术能够利用大数据集群的资源,可以大大提升资源的利用率,如 Dockeron Yarn。
接着上面讲的统一日志服务,其输出的日志最终是变成数据到数据高速公路上供后续的数据处理程序消费的。这中间的过程包括日志的收集和传输。
收集:统一日志服务将日志打印在日志服务上以后,须要日志收集机制将其集中起来。目前,常见的日志收集方案有:Scribe、Chukwa、Kakfa 和 Flume。对好比下图所示:
传输:经过消息队列将数据传输到数据处理服务中。对于日志来讲,一般选择 Kafka 这个消息队列便可。
此外,这里还有一个关键的技术就是数据库和数据仓库间的数据同步问题,即将须要分析的数据从数据库中同步到诸如 Hive 这种数据仓库时使用的方案。可使用 Apache Sqoop 进行基于时间戳的数据同步,此外,阿里开源的 Canal 实现了基于 binlog 增量同步,更加适合通用的同步场景,可是基于 Canal 仍是须要作很多的业务开发工做。
离线数据分析是能够有延迟的,通常针对的是非实时需求的数据分析工做,产生的也是延迟一天的报表。目前最经常使用的离线数据分析技术除了 Hadoop 还有 Spark。相比 Hadoop,Spark 性能上有很大优点,固然对硬件资源要求也高。其中,Hadoop 中的 Yarn 做为资源管理调度组件除了服务于 MR 还能够用于 Spark(Spark on Yarn),Mesos 则是另外一种资源管理调度系统。
对于 Hadoop,传统的 MR 编写很复杂,也不利于维护,能够选择使用 Hive 来用 SQL 替代编写 MR。而对于 Spark,也有相似 Hive 的 Spark SQL。
此外,对于离线数据分析,还有一个很关键的就是数据倾斜问题。所谓数据倾斜指的是 region 数据分布不均,形成有的结点负载很低,而有些却负载很高,从而影响总体的性能。处理好数据倾斜问题对于数据处理是很关键的。
相对于离线数据分析,实时数据分析也叫在线数据分析,针对的是对数据有实时要求的业务场景,如广告结算、订单结算等。目前,比较成熟的实时技术有 Storm 和 Spark Streaming。相比起Storm,Spark Streaming 其实本质上仍是基于批量计算的。若是是对延迟很敏感的场景,仍是应该使用 Storm。除了这二者,Flink 则是最近很火的一个分布式实时计算框架,其支持 Exactly Once的语义,在大数据量下具备高吞吐低延迟的优点,而且可以很好的支持状态管理和窗口统计,但其文档、API管理平台等都还须要完善。
实时数据处理通常状况下都是基于增量处理的,相对于离线来讲并不是可靠的,一旦出现故障(如集群崩溃)或者数据处理失败,是很难对数据恢复或者修复异常数据的。所以结合离线+实时是目前最广泛采用的数据处理方案。Lambda架构就是一个结合离线和实时数据处理的架构方案。
此外,实时数据分析中还有一个很常见的场景:多维数据实时分析,即可以组合任意维度进行数据展现和分析。目前有两种解决此问题的方案:ROLAP 和 MOLAP。
如上一小节所述,ROLAP的方案大多数状况下用户离线数据分析,知足不了实时的需求,所以 MOLAP 是多维数据实时分析的经常使用方案。对于其中经常使用的三个框架,对好比下:
其中,Druid相对比较轻量级,用的人较多,比较成熟。
离线和实时数据分析产生的一些报表是给数据分析师、产品经理参考使用的,可是不少状况下,线上的程序并不能知足这些需求方的需求。这时候就须要需求方本身对数据仓库进行查询统计。针对这些需求方,SQL上手容易、易描述等特色决定了其多是一个最为合适的方式。所以提供一个 SQL 的即席查询工具可以大大提升数据分析师、产品经理的工做效率。Presto、Impala、Hive 都是这种工具。若是想进一步提供给需求方更加直观的 ui 操做界面,能够搭建内部的 Hue。
对于面向用户的线上服务,发生故障是一件很严重的事情。所以,作好线上服务的故障检测告警是一件很是重要的事情。能够将故障监控分为如下两个层面的监控:
监控还有一个关键的步骤就是告警。告警的方式有不少种:邮件、IM、短信等。考虑到故障的重要性不一样、告警的合理性、便于定位问题等因素,有如下建议:
故障告警以后,那么最最关键的就是应对了。对于创业公司来讲,24小时待命是必备的素质,当遇到告警的时候,须要尽快对故障作出反应,找到问题所在,并能在可控时间内解决问题。对于故障问题的排查,基本上都是依赖于日志的。只要日志打的合理,通常状况下是可以很快定位到问题所在的,可是若是是分布式服务,而且日志数据量特别大的状况下,如何定位日志就成为了难题。这里有几个方案: