使用Java后端技术的目的就是构建业务应用,为用户提供在线或者离线服务。所以,一个业务应用须要哪些技术、依赖哪些基础设施就决定了须要掌握的后端技术有哪些。纵观整个互联网技术体系再结合公司的目前情况,笔者认为必不可少或者很是关键的后端基础技术/设施以下图所示:ios
这里的后端基础设施主要指的是应用在线上稳定运行须要依赖的关键组件或者服务。开发或者搭建好以上的后端基础设施,通常状况下是可以支撑很长一段时间内的业务的。此外,对于一个完整的架构来讲,还有不少应用感知不到的系统基础服务,如负载均衡、自动化部署、系统安全等,并无包含在本章的描述范围内。nginx
在移动APP的开发过程当中,一般后端提供的接口须要如下功能的支持:git
通常的作法,使用Nginx作负载均衡,而后在每一个业务应用里作API接口的访问权限控制和用户鉴权,更优化一点的方式则是把后二者作成公共类库供全部业务调用。但从整体上来看,这三种特性都属于业务的公共需求,更可取的方式则是集成到一块儿做为一个服务,既能够动态地修改权限控制和鉴权机制,也能够减小每一个业务集成这些机制的成本。这种服务就是API网关,能够选择本身实现。也可使用开源软件实现,如Kong和Netflix Zuul。API网关通常架构以下图所示:web
可是以上方案的一个问题是因为全部API请求都要通过网关,它很容易成为系统的性能瓶颈。所以,能够采起的方案是:去掉API网关,让业务应用直接对接统一认证中心,在基础框架层面保证每一个API调用都须要先经过统一认证中心的认证,这里能够采起缓存认证结果的方式避免对统一认证中心产生过大的请求压力。spring
业务应用分为:在线业务应用和内部业务应用。mongodb
业务应用基于后端的基础框架开发,针对Java后端来讲,应该有如下几个框架:docker
通常来讲,以上几个框架便可以完成一个后端应用的雏形。数据库
缓存、数据库、搜索引擎、消息队列这四者都是应用依赖的后端基础服务,他们的性能直接影响到了应用的总体性能,有时候你代码写的再好也许就是由于这些服务致使应用性能没法提高上去。编程
无论是业务应用、依赖的后端服务仍是其余的各类服务,最终仍是要依赖于底层文件存储的。一般来讲,文件存储须要知足的特性有:可靠性、容灾性、稳定性,即要保证存储的数据不会轻易丢失,即便发生故障也可以有回滚方案,也要保证高可用。在底层能够采用传统的RAID做为解决方案,再上一层,目前Hadoop的HDFS则是最为广泛的分布式文件存储方案,固然还有NFS、Samba这种共享文件系统也提供了简单的分布式存储的特性。后端
此外,若是文件存储确实成为了应用的瓶颈或者必须提升文件存储的性能从而提高整个系统的性能时,那么最为直接和简单的作法就是抛弃传统机械硬盘,用SSD硬盘替代。像如今不少公司在解决业务性能问题的时候,最终的关键点每每就是SSD。这也是用钱换取时间和人力成本最直接和最有效的方式。在数据库部分描述的SSDB就是对LevelDB封装以后,利用SSD硬盘的特性的一种高性能KV数据库。
至于HDFS,若是要使用上面的数据,是须要经过Hadoop的。相似xx on Yarn的一些技术就是将非Hadoop技术跑在HDFS上的解决方案。
统一认证中心,主要是对APP用户、内部用户、APP等的认证服务,包括
之因此须要统一认证中心,就是为了可以集中对这些全部APP都会用到的信息进行管理,也给全部应用提供统一的认证服务。尤为是在有不少业务须要共享用户数据的时候,构建一个统一认证中心是很是必要的。此外,经过统一认证中心构建移动APP的单点登陆也是水到渠成的事情:模仿Web的机制,将认证后的信息加密存储到本地存储中供多个APP使用。
目前不少大的在线Web网站都是有单点登陆系统的,通俗的来讲就是只须要一次用户登陆,就可以进入多个业务应用(权限能够不相同),很是方便用户的操做。而在移动互联网公司中,内部的各类管理、信息系统甚至外部应用一样也须要单点登陆系统。
目前,比较成熟的、用的最多的单点登陆系统应该是耶鲁大学开源的CAS, 能够基于 https://github.com/apereo/cas/tree/master/cas-server-webapp 来定制开发的。
基本上,单点登陆的原理都相似下图所示:
在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调用将日志打印到日志服务器上。
数据是最近几年很是火的一个领域。从《精益数据分析》到《增加黑客》,都是在强调数据的非凡做用。不少公司也都在经过数据推进产品设计、市场运营、研发等。这里须要说明的一点是,只有当你的数据规模真的到了单机没法处理的规模才应该上大数据相关技术,千万不要为了大数据而大数据。不少状况下使用单机程序+MySQL就能解决的问题非得上Hadoop即浪费时间又浪费人力。
这里须要补充一点的是,对于不少公司,尤为是离线业务并无那么密集的公司,在不少状况下大数据集群的资源是被浪费的。所以诞了 xx on Yarn 一系列技术让非Hadoop系的技术能够利用大数据集群的资源,可以大大提升资源的利用率,如Dockeron Yarn。
接着上面讲的统一日志服务,其输出的日志最终是变成数据到数据高速公路上供后续的数据处理程序消费的。这中间的过程包括日志的收集和传输。
收集:统一日志服务将日志打印在日志服务上以后,须要日志收集机制将其集中起来。目前,常见的日志收集方案有:Scribe、Chukwa、Kakfa和Flume。对好比下图所示:
此外,Logstash也是一个能够选择的日志收集方案,不一样于以上的是,它更倾向于数据的预处理,且配置简单、清晰,常常以ELK(Elasticsearch + Logstash + Kibana)的架构用于运维场景中。
传输:经过消息队列将数据传输到数据处理服务中。对于日志来讲,一般选择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 | 实时处理分析 | Java | JSON | 实时聚合 |
Pinot | 实时处理分析 | Java | JSON | 实时聚合 |
Kylin | OLAP分析引擎 | Java | JDBC/OLAP | 预处理、cache |
其中,Druid相对比较轻量级,用的人较多,比较成熟。
离线和实时数据分析产生的一些报表是给数据分析师、产品经理参考使用的,可是不少状况下,线上的程序并不能知足这些需求方的需求。这时候就须要需求方本身对数据仓库进行查询统计。针对这些需求方,SQL上手容易、易描述等特色决定了其多是一个最为合适的方式。所以提供一个SQL的即席查询工具可以大大提升数据分析师、产品经理的工做效率。Presto、Impala、Hive都是这种工具。若是想进一步提供给需求方更加直观的ui操做界面,能够搭建内部的Hue。
对于面向用户的线上服务,发生故障是一件很严重的事情。所以,作好线上服务的故障检测告警是一件很是重要的事情。能够将故障监控分为如下两个层面的监控:
监控还有一个关键的步骤就是告警。告警的方式有不少种:邮件、IM、短信等。考虑到故障的重要性不一样、告警的合理性、便于定位问题等因素,有如下建议:
故障告警以后,那么最最关键的就是应对了。对于创业公司来讲,24小时待命是必备的素质,当遇到告警的时候,须要尽快对故障作出反应,找到问题所在,并能在可控时间内解决问题。对于故障问题的排查,基本上都是依赖于日志的。只要日志打的合理,通常状况下是可以很快定位到问题所在的,可是若是是分布式服务,而且日志数据量特别大的状况下,如何定位日志就成为了难题。这里有几个方案: