谈谈互联网后端基础设施

对于一个互联网企业,后端服务是必不可少的一个组成部分。抛开业务应用来讲,往下的基础服务设施作到哪些才可以保证业务的稳定可靠、易维护、高可用呢?纵观整个互联网技术体系再结合公司的目前情况,我的认为必不可少或者很是关键的后端基础技术/设施以下图所示:




这里的后端基础设施主要指的是应用在线上稳定运行须要依赖的关键组件/服务等。开发或者搭建好以上的后端基础设施,通常状况下是可以支撑很长一段时间内的业务的。此外,对于一个完整的架构来讲,还有不少应用感知不到的系统基础服务,如负载均衡、自动化部署、系统安全等,并无包含在本文的描述范围内。


Api网关


在移动app的开发过程当中,一般后端提供的接口须要如下功能的支持:


    负载均衡

    api访问权限控制

    用户鉴权


通常的作法,使用nginx作负载均衡,而后在每一个业务应用里作api接口的访问权限控制和用户鉴权,更优化一点的方式则是把后二者作成公共类库供全部业务调用。但从整体上来看,这三种特性都属于业务的公共需求,更可取的方式则是集成到一块儿做为一个服务,既能够动态地修改权限控制和鉴权机制,也能够减小每一个业务集成这些机制的成本。这种服务就是Api网关(http://blog.csdn.net/pzxwhc/article/details/49873623),能够选择本身实现,也可使用开源软件实现,如Kong。以下图所示:




可是以上方案的一个问题是因为全部api请求都要通过网关,它很容易成为系统的性能瓶颈。所以,能够采起的方案是:去掉api网关,让业务应用直接对接统一认证中心,在基础框架层面保证每一个api调用都须要先经过统一认证中心的认证,这里能够采起缓存认证结果的方式避免对统一认证中心产生过大的请求压力。


业务应用和后端基础框架


业务应用分为:在线业务应用和内部业务应用。


    在线业务应用:直接面向互联网用户的应用、接口等,典型的特色就是:请求量大、高并发、高可用、对故障的容忍度低。

    内部业务应用:这个是面向公司内部的应用。好比,内部数据管理平台、广告投放平台等。相比起在线业务应用,其特色: 数据保密性高、压力小、并发量小、容许故障的发生。


业务应用基于后端的基础框架开发,针对Java后端来讲,应该有的几个框架以下:


    MVC框架:从十年前流行的Struts一、2到如今最为推崇的SpringMVC、Jersey以及国人开发的JFinal、阿里的WebX等等,这些框架尤为是后面流行的这些都是各有千秋的。选型的主要因素是看你的团队是否有一个对某框架可以作二次开发、定制的人在。不少时候,针对这些通用的框架,你是须要作一些特定的开发才能知足特定的需求的。好比,不少团队传递参数使用的都是UnderScore的命名法(下划线链接单词),可是Java中确是使用LowCamel命名的。对于SpringMVC,能够经过注解的alias来指定,但这样须要对每个参数都要指定alias有点效率过低,此外ModelAttribute也不支持别名,更好的方式是在框架层面统一对参数作Camel命名的转换达到目的。

    IOC框架:ioc带来的好处无须多言。目前Java中最为流行的Spring自诞生就自然支持IOC。

    ORM框架:MyBatis是目前最为流行的orm框架。此外,Spring ORM中提供的JdbcTemplate也很不错。固然,对于分库分表、主从分离这些需求,通常就须要实现本身的ORM框架来支持了,像阿里的tddl、当当的sharding-jdbc(从datasource层面解决了分库分表、读写分离的问题,对应用透明、零侵入)。此外,为了在服务层面统一解决分库分表、主从分离、主备切换、缓存、故障恢复等问题,不少公司都是有本身的数据库中间件的,好比阿里的Cobar、360的Atlas、网易的DDB,还有官方提供的MySQL Proxy以及开源的MyCat、kingshard和收费的oneproxy。目前,线上有必定规模使用的应该是kingshard,固然若是不缺钱也能够上oneproxy。

    缓存框架:缓存框架主要指的是对redis、memcached这些缓存服务器的操做统一封装,通常使用Spring的RedisTemplate便可,也可使用jedis作本身的封装,支持客户端分布式方案、主从等。

    JavaEE应用性能检测框架:对于线上的JavaEE应用,须要有一个统一的框架集成到每个业务中检测每个请求、方法调用、jdbc链接、redis链接等的耗时、状态等。jwebap是一个可使用的性能检测工具,但因为其已经不少年没有更新,有可能的话建议基于此项目作二次开发。


通常来讲,以上几个框架便可以完成一个后端应用的雏形。


对于这些框架来讲,最为关键的是根据团队技术构成选择最合适的,有能力开发本身的框架则更好。此外,这里须要提供一个后端应用的模板或生成工具(如maven的archetype)给团队成员使用,可让你们在开发新的应用的时候,迅速的生成雏形应用,而无需再作一些框架搭建的重复性劳动。


缓存、数据库、搜索引擎、消息队列


缓存、数据库、搜索引擎、消息队列这四者都是应用依赖的后端基础服务,他们的性能直接影响到了应用的总体性能,有时候你代码写的再好也许就是由于这些服务致使应用性能没法提高上去。


缓存


如缓存五分钟法则所讲:若是一个数据频繁被访问,那么就应该放内存中。这里的缓存就是一种读写效率都很是高的存储方案,可以应对高并发的访问请求,一般状况下也不须要持久化的保证。但相对其余存储来讲,缓存通常是基于内存的,成本比较昂贵,所以不能滥用。


缓存能够分为:本地缓存和分布式缓存。


    本地缓存:主要指的是内存中的缓存机制。在Java中,Google Guava中就提供了本地缓存的实现机制。固然使用java的ConncurrentHashMap你也能够实现本身的本地缓存方案。

    分布式缓存:指的单独的缓存服务。几年前比较流行的是memcached,但其只是一个KV的存储,支持的数据结构太少。如今最为流行的就是Redis,可以支持丰富的数据结构,基于事件驱动的单线程非阻塞IO也可以应对高并发的场景。集群方案除了官方的redis cluster, 目前比较流行的还有豌豆荚的codis、twitter的twemproxy。


对于缓存的使用,须要注意如下几点:


    缓存的失效机制:当给某一个key设置了有效期,那么缓存什么时候对此key进行删除呢?通常来讲会有如下几种方式:

    守护进程定时去扫描key,找到已经失效的key,而后删除

    读取key的时候先去判断key是否失效,若是失效则删除并返回空。

    缓存的淘汰机制:是当缓存内存达到上限时如何删除缓存中的key。Redis提供了如下数据淘汰策略:

    volatile-lru:从已设置过时时间的数据集中挑选最近最少使用的数据淘汰

    volatile-ttl:从已设置过时时间的数据集中挑选将要过时的数据淘汰

    volatile-random:从已设置过时时间的数据集中任意选择数据淘汰

    allkeys-lru:从数据集中挑选最近最少使用的数据淘汰

    allkeys-random:从数据集中任意选择数据淘汰

    no-enviction(驱逐):禁止驱逐数据


对于其具体的实现机制,能够参考《Redis设计与实现》一书


    缓存的更新机制: 一般来讲有四种方式:Cache aside, Read through, Write through, Write behind caching,具体的可见陈皓大神的这篇总结:缓存更新的套路。

    缓存的服务过载保护:缓存的服务过载指的是因为缓存失效,而引发后端服务的压力骤增,进一步产生雪崩效应。这个现象和缓存更新是相关的,采起何种策略在缓存失效的时候去更新缓存直接决定了服务过载的保护机制。一般的分为客户端和服务端的应对方案。前者的方案有:基于超时的简单模式、基于超时的常规模式、基于刷新的简单模式、基于刷新的常规模式、基于刷新的续费模式。后者的方案则是很常见的流量控制和服务降级。具体的能够看美团技术团队总结的这篇文章:Cache应用中的服务过载案例研究。


数据库


数据库是后端开发中很是常见的一个服务组件。对于数据库的选型,要根据业务的特色和数据结构的特色来决定。


从存储介质上,数据库能够分为:


    内存数据库: 数据主要存储在内存中,同时也能够采起措施对数据进行持久化到硬盘中。如Redis、H2DB的内存模式。对于这种数据库,因为内存成本昂贵,所以必定要作好存储的量化分析、容量预估,防止内存不足形成服务不可用。

    硬盘数据库:数据存储在硬盘上的这种数据库是最为常见的。MySQL、Oracle、Postgresql、HBASE、H2DB、SqlLite等等都是硬盘数据库。此外,SSDB是基于SSD硬盘的KV数据库,支持的数据接口很丰富,是Redis的另一个选择。


从存储数据类型、数据模式上,数据库能够分为:


    关系型数据库:MySQL、Oracle、Postgresql都是关系型数据库的,是采用关系模型(关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织)来组织数据的数据库。

    非关系型数据库:非关系型数据库是相对关系型数据库来说的。以键值对存储,且结构不固定,每个元组能够有不同的字段,每一个元组能够根据须要增长一些本身的键值对,这样就不会局限于固定的结构,能够减小一些时间和空间的开销。可是,其没有关系型数据库那种严格的数据模式,并不适合复杂的查询以及须要强事务管理的业务。非关系型数据库又能够分为:

    KV数据库:主要以(key,value)键值对存储数据的数据库。以Redis、RocksDB(levelDB)、SSDB为表明。

    文档数据库:整体形式上也是键值对的形式,可是值里面又能够有各类数据结构:数组、键值对、字符串等等。以mongodb、couchdb为表明。

    列数据库:也叫做稀疏大数据库,通常是用来存储海量数据的。相对于行数据库,这种数据库是以列为单位存储数据在介质上的。以Hbase、Cassendra为表明。


和数据库相关的一个很重要的就是数据库的索引。有一种说法是:“掌握了索引就等于掌握了数据库”。暂且不去评判此说法是否真的准确,但索引的确关系着数据库的读写性能。须要对数据库的索引原理作到足够的了解才能更好的使用各类数据库。一般来讲,Mysql、Oracle、Mongodb这些都是使用的B树做为索引,是考虑到传统硬盘的特色后兼顾了读写性能以及范围查找需求的选择,而Hbase用得LSM则是为了提升写性能对读性能作了牺牲。


搜索引擎


搜索引擎也是后端应用中一个很关键的组件,尤为是对内容类、电商类的应用,经过关键词、关键字搜索内容、商品是一个很常见的用户场景。比较成熟的开源搜索引擎有Solr和Elasticsearch,不少中小型互联网公司搜索引擎都是基于这两个开源系统搭建的。它们都是基于Lucence来实现的,不一样之处主要在于termIndex的存储、分布式架构的支持等等。


对于搜索引擎的使用,从系统熟悉、服务搭建、功能定制,须要花费较长时间。在这个过程当中,须要注意如下问题:


    搜索引擎与公司现有数据系统的集成。现有的持久化、供搜索的数据的载体是什么, 如何让搜索引擎在全量和增量建索引过程当中无缝集成原来的数据载体,才能发挥搜索引擎自身的实时性, 水平扩展性(性能与容量和机器数量成正比)等优点。

    和数据库同样,对搜索引擎的索引机制也须要作到深刻的了解。


更为详细的对于搜索引擎的工程化实践能够参考有zan工程师的这篇文章:有zan搜索引擎实践(工程篇)


另外,搜索引擎还能够用在数据的多维分析上,就是GrowingIO、MixPanel中的能够任意维度查询数据报表的功能。固然,druid也许是一个更好的实现多维分析的方案,官方也有其与es的比较:http://druid.io/docs/latest/comparisons/druid-vs-elasticsearch.html。


消息队列


软件的组织结构,从开始的面向组件到SOA、SAAS是一个逐渐演变的过程。而到了今天微服务盛行的时代,你都很差意思说本身的系统只是单一的一个系统而没有解耦成一个个service。固然,小的系统的确没有拆分的必要性,但一个复杂的系统拆成一个个service作微服务架构确实是不得不作的事情。


那么问题就来了,service之间的通讯如何来作呢?使用什么协议?经过什么方式调用?都是须要考虑的问题。


先抛开协议不谈,service之间的调用方式能够分为同步调用以及异步调用。同步调用的方式无需多说,那么异步调用是怎么进行的呢?一种很常见的方式就是使用消息队列,调用方把请求放到队列中便可返回,而后等待服务提供方去队列中去获取请求进行处理,而后把结果返回给调用方便可(能够经过回调)。


异步调用就是消息中间件一个很是常见的应用场景。此外,消息队列的应用场景还有如下:


    解耦:一个事务,只关心核心的流程,须要依赖其余系统但不那么重要的事情,有通知便可,无须等待结果。

    最终一致性:指的是两个系统的状态保持一致,要么都成功,要么都失败,能够有必定的延迟,只要最终达到一致性便可。

    广播:这是消息队列最基本的功能。生产者只须要发布消息,无须关心有哪些订阅者来消费消息。

    错峰与流控:当上下游系统处理能力不一样的时候就须要相似消息队列的方式作为缓冲区来隔开两个系统。


目前主流的消息队列软件,主要有如下几种:


    ActiveMQ:Java中最为简单的消息队列,是对JMS的实现,没有规定消息的顺序、安全、重发等特性。

    RabbitMQ:是对AMQP协议的实现,对于消息的顺序性、安全、重发等都作了很好的支持。比较适合不容许数据丢失、有事务需求的业务场景下的消息传输。

    Kafka:是基于Log的消息队列,底层依赖于文件的顺序读取,是append-only的。适合对数据丢失不敏感、强调性能的一些海量日志传输场景中。是最近几年大数据领域很火的一个技术。

    ZeroMQ:是一个网络编程的Pattern库,将常见的网络请求形式(分组管理,连接管理,发布订阅等)模式化、组件化,简而言之socket之上、MQ之下。对于MQ来讲,网络传输只是它的一部分,更多须要处理的是消息存储、路由、Broker服务发现和查找、事务、消费模式(ack、重投等)、集群服务等。


文件存储


无论是业务应用、依赖的后端服务仍是其余的各类服务,最终仍是要依赖于底层文件存储的。一般来讲,文件存储须要知足的特性有:可靠性、容灾性、稳定性,即要保证存储的数据不会轻易丢失,即便发生故障也可以有回滚方案,也要保证高可用率。在底层能够采用传统的RAID做为解决方案,再上一层,目前hadoop的hdfs则是最为广泛的分布式文件存储方案,固然还有NFS、Samba这种共享文件系统也提供了简单的分布式存储的特性。


此外,若是文件存储确实成为了应用的瓶颈或者必须提升文件存储的性能从而提高整个系统的性能时,那么最为直接和简单的作法就是抛弃传统机械硬盘,用SSD硬盘替代。像如今不少公司在解决业务性能问题的时候,最终的关键点每每就是SSD。这也是用钱换取时间和人力成本最直接和最有效的方式。在数据库部分描述的SSDB就是对LevelDB封装以后,利用SSDB的特性的一种高性能KV数据库。


至于HDFS,若是要使用上面的数据,是须要经过hadoop的。相似xx on yarn的一些技术就是将非hadoop技术跑在hdfs上的解决方案(固然也是为了使用MR)。


统一认证中心


统一认证中心,主要是对app用户、内部用户、app等的认证服务,包括


    用户的注册、登陆验证、token鉴权

    内部信息系统用户的管理和登陆鉴权

    App的管理,包括app的secret生成,app信息的验证(如验证接口签名)等。


之因此须要统一认证中心,就是为了可以集中对这些全部app都会用到的信息进行管理,也给全部应用提供统一的认证服务。尤为是在有不少业务须要共享用户数据的时候,构建一个统一认证中心是很是必要的。此外,经过统一认证中心构建移动app的单点登陆也是水到渠成的事情(模仿web的机制,将认证后的信息加密存储到本地磁盘中供多个app使用)。


单点登陆系统


目前不少大的在线web网站都是有单点登陆系统的,通俗的来讲就是只须要一次用户登陆,就可以进入多个业务应用(权限能够不相同),很是方便用户的操做。而在移动互联网公司中,内部的各类管理、信息系统一样也须要单点登陆系统。目前,比较成熟的、用的最多的单点登陆系统应该是耶鲁大学开源的CAS, 能够基于https://github.com/apereo/cas/tree/master/cas-server-webapp来定制开发的。此外,国人开源的kisso的这个也不错。基本上,单点登陆的原理都相似下图所示:





统一配置中心


在Java后端应用中,一种读写配置比较通用的方式就是将配置文件写在propeties、yaml、HCON文件中,修改的时候只须要更新文件从新部署便可,能够作到不牵扯代码层面改动的目的。统一配置中心,则是基于这种方式之上的统一对全部业务或者基础后端服务的相关配置文件进行管理的统一服务, 具备如下特性:


    可以在线动态修改配置文件并生效

    配置文件能够区分环境(开发、测试、生产等)

    使用方便: 在java中能够经过注解、xml配置的方式引入相关配置


disconf是能够在生产环境使用的一个方案,也可能根据本身的需求开发本身的配置中心(能够选择zookeeper做为配置存储)。


服务治理框架


对于外部API调用或者客户端对后端api的访问,可使用http协议或者说restful(固然也能够直接经过最原始的socket来调用)。但对于内部服务间的调用,通常都是经过RPC机制来调用的。目前主流的RPC协议有:


    RMI

    Hessian

    Thrift

    Dubbo


这些RPC协议各有优劣点,须要针对业务需求作出相应的最好的选择。


这样,当你的系统服务在逐渐增多,RPC调用链愈来愈复杂,不少状况下,须要不停的更新文档来维护这些调用关系。一个对这些服务进行管理的框架能够大大节省所以带来的繁琐的人力工做。


传统的ESB(企业服务总线)本质就是一个服务治理方案,但esb做为一种proxy的角色存在于client和server之间,全部请求都须要通过esb,使得esb很容易成为性能瓶颈。所以,基于传统的esb,更好的一种设计以下图所示:




如图,以配置中心为枢纽,调用关系只存在于client和提供服务的server之间,就避免了传统esb的性能瓶颈问题。对于这种设计,esb应该支持的特性以下:


    服务提供方的注册、管理

    服务消费者的注册、管理

    服务的版本管理、负载均衡、流量控制、服务降级等

    服务的容错、熔断等


阿里开源的dubbo则对以上作了很好的实现,也是目前不少公司都在使用的方案。但因为某些缘由,dubbo现已再也不维护,推荐你们使用当当后来维护的dubbox。


统一调度中心


在不少业务中,定时调度是一个很是广泛的场景,好比定时去抓取数据、定时刷新订单的状态等。一般的作法就是针对各自的业务依赖Linux的cron机制或者java中的quartz。统一调度中心则是对全部的调度任务进行管理,这样可以统一对调度集群进行调优、扩展、任务管理等。azkaban和oozie是hadoop的流式工做管理引擎,也能够做为统一调度中心来使用。固然,你也可使用cron或者quartz来实现本身的统一调度中心。


    根据cron表达式调度任务

    动态修改、中止、删除任务

    支持任务工做流:好比一个任务完成以后再执行下一个任务

    任务支持脚本、代码、url等多种形式

    任务执行的日志记录、故障报警


对于Java的quartz这里须要说明一下:这个quartz须要和spring quartz区分,后者是spring对quartz框架的简单实现也是目前使用的最多的一种调度方式。但其并无作高可用集群的支持。而quartz虽然有集群的支持,可是配置起来很是复杂。如今不少方案都是使用zookeeper来实现spring quartz集群的。这里有一个国人开源的uncode-shcedule对此实现的还不错,能够根据本身的业务需求作二次开发。此外,当当开源的elastic-job则在此之上又加入了弹性资源利用等更为强大的功能。


统一日志服务


日志是开发过程必不可少的东西。有时候,打印日志的时机、技巧是很能体现出工程师编码水平的。毕竟,日志是线上服务可以定位、排查异常最为直接的信息。


一般的,将日志分散在各个业务中很是不方便对问题的管理和排查。统一日志服务则使用单独的日志服务器记录日志,各个业务经过统一的日志框架将日志输出到日志服务器上。


能够经过实现log4j后者logback的appender来实现统一日志框架,而后经过RPC调用将日志打印到日志服务器上。


数据基础设施


数据是最近几年很是火的一个领域。从《精益数据分析》到《增加黑客》,都是在强调数据的非凡做用。不少公司也都在经过数据推进产品设计、市场运营、研发等。详细的可见以前的一篇《数据杂谈》,对数据相关的东西作过一些总结。这里须要说明的一点是,只有当你的数据规模真的到了单机没法处理的规模才应该上大数据相关技术,千万不要为了大数据而大数据。不少状况下使用单机程序+mysql就能解决的问题非得上hadoop即浪费时间又浪费人力。


这里须要补充一点的是,对于不少公司,尤为是离线业务并无那么密集的公司,在不少状况下大数据集群的资源是被浪费的。所以诞生了xx on yarn一系列技术让非hadoop系的技术能够利用大数据集群的资源,可以大大提升资源的利用率,如Docker on yarn(Hulu的VoidBox)。


数据高速公路


接着上面讲的统一日志服务,其输出的日志最终是变成数据到数据高速公路上供后续的数据处理程序消费的。这中间的过程包括日志的收集、传输。


    收集:统一日志服务将日志打印在日志服务上以后,须要日志收集机制将其集中起来。目前,常见的日志收集方案有:scribe、Chukwa、Kakfa和Flume。对好比下图所示:




    传输:经过消息队列将数据传输到数据处理服务中。对于日志来讲,一般选择kafka这种消息队列便可。


此外,这里还有一个关键的技术就是数据库和数据仓库间的数据同步问题,即将须要分析的数据从数据库中同步到诸如hive这种数据仓库时使用的方案。比较简单的、用的也比较多的可使用sqoop进行基于时间戳的数据同步,此外,阿里开源的canal实现了基于binlog增量同步,更加适合通用的同步场景,可是基于canal你仍是须要作很多的业务开发工做的。推荐另外一款国人开源的MySQL-Binlog,原理和canal相似,默认提供了任务的后台管理功能,只须要实现接收到binlog后的处理逻辑便可。


离线数据分析


离线数据分析是能够有延迟的,通常针对是非实时需求的数据分析工做,产生的也是T-1的报表。目前最经常使用的离线数据分析技术除了hadoop还有spark。相比hadoop,spark性能上有很大优点,固然对硬件资源要求也高。


对于hadoop,传统的MR编写很复杂,也不利于维护,能够选择使用hive来用sql替代编写mr,可是前提务必要对hive的原理作到了解。能够参见美团的这篇博文来学习:Hive SQL的编译过程。而对于spark,也有相似hive的spark sql。


此外,对于离线数据分析,还有一个很关键的就是数据倾斜问题。所谓数据倾斜指的是region数据分布不均,形成有的结点负载很低,而有些却负载很高,从而影响总体的性能。所以,处理好数据倾斜问题对于数据处理是很关键的。对于hive的数据倾斜,可见:hive大数据倾斜总结。对于spark的倾斜问题,可见:Spark性能优化指南——高级篇。


实时数据分析


相对于离线数据分析,实时数据分析也叫在线数据分析,针对的是对数据有实时要求的业务场景,如广告结算、订单结算等。目前,比较成熟的实时技术有storm和spark streaming。相比起storm,spark streaming其实本质上仍是基于批量计算的。若是是对延迟很敏感的场景,仍是应该使用storm。


对于实时数据分析,须要注意的就是实时数据处理结果写入存储的时候,要考虑并发的问题,虽然对于storm的bolt程序来讲不会有并发的问题,可是写入的存储介质是会面临多任务同时读写的。一般采用的方案就是采用时间窗口的方式对数据作缓冲后批量写入。


此外,实时数据处理通常状况下都是基于增量处理的,相对于离线来讲并不是可靠的,一旦出现故障(如集群崩溃)或者数据处理失败,是很难对数据恢复或者修复异常数据的。所以结合离线+实时是目前最广泛采用的数据处理方案。Lambda架构就是一个结合离线和实时数据处理的架构方案。


数据即席分析


离线和实时数据分析产生的一些报表是给数据分析师、产品经理参考使用的,可是不少状况下,线上的程序并不能知足这些需求方的需求。这时候就须要需求方本身对数据仓库进行查询统计。针对这些需求方,SQL上手容易、易描述等特色决定了其多是一个最为合适的方式。所以提供一个SQL的即席查询工具可以大大提升数据分析师、产品经理的工做效率。Presto、Impala、Hive都是这种工具。若是想进一步提供给需求方更加直观的ui操做界面,能够搭建内部的Hue。




故障监控


对于面向用户的线上服务,发生故障是一件很严重的事情。所以,作好线上服务的故障检测告警是一件很是重要的事情。能够将故障监控分为如下两个层面的监控:


    系统监控:主要指的对主机的带宽、cpu、内存、硬盘、io等硬件资源的监控。这可使用开源的nagios、cacti等开源软件进行监控。目前,市面上也有不少第三方服务可以提供对于主机资源的监控,如监控宝等。对于分布式服务集群(如hadoop、storm、kafka、flume等集群)的监控则可使用ganglia。此外,小米开源的OpenFalcon也很不错,涵盖了系统监控、JVM监控等,也支持自定义的监控机制。

    业务监控:是在主机资源层面以上的监控,好比app的pv、uv数据异常、交易失败等。须要业务中加入相关的监控代码,好比在异常抛出的地方,加一段日志记录。


监控还有一个关键的步骤就是告警。告警的方式有不少种:邮件、im、短信等。考虑到故障的重要性不一样、告警的合理性、便于定位问题等因素,有如下建议:


    告警日志要记录发生故障的机器id,尤为是在集群服务中,若是没有记录机器id,那么对于后续的问题定位会很困难。


    要对告警作聚合,不要每个故障都单独进行告警,这样会对工程师形成极大的困扰。


    要对告警作等级划分,不能对全部告警都作一样的优先级处理。


    使用微信作为告警软件,可以在节省短信成本的状况下,保证告警的到达率。


故障告警以后,那么最最关键的就是应对了。对于创业公司来讲,24小时待命是必备的素质,当遇到告警的时候,须要尽快对故障作出反应,找到问题所在,并能在可控时间内解决问题。对于故障问题的排查,基本上都是依赖于日志的。只要日志打的合理,通常状况下是可以很快定位到问题所在的,可是若是是分布式服务,而且日志数据量特别大的状况下,如何定位日志就成为了难题。这里有几个方案:


    创建ELK(Elastic+Logstash+Kibana)日志集中分析平台,便于快速搜索、定位日志。对于ELK的介绍,能够见:使用Elasticsearch + Logstash + Kibana搭建日志集中分析平台实践


    创建分布式请求追踪系统(也能够叫全链路监测系统),对于分布式系统尤为是微服务架构,可以极大的方便在海量调用中快速定位并收集单个异常请求信息,也能快速定位一条请求链路的性能瓶颈。Google的Dapper、惟品会的Mercury、阿里的鹰眼、新浪的WatchMan都是相似的思路。此外,腾讯的染色日志机制本质上也是在链路追踪之上根据响应信息作了染色机制。


Netflix组件


近几年Netflix开源了其内部不少的服务:https://github.com/Netflix,包括大数据、构建交付工具、通用运行时服务类库、数据持久化、安全等。里面有一些对应了上面所说的基础设施:


1. zuul这是Netflix全部后端服务最前端的一道门,也就是咱们上面说的Api网关, 主要包含了如下功能:


    认证受权和安全:识别合法的外部请求,拒绝非法的。

    监控:跟踪记录全部有意义的数据以便于给咱们一个精确的产品视图。

    动态路由:根据须要动态把请求路由到合适的后端服务上。

    压力测试:渐进式的增长对集群的压力直到最大值。

    限流:对每一种类型的请求都限定流量,拒绝超出的请求。

    静态响应控制:对于某些请求直接在边缘返回而不转发到后端集群。

    多区域弹性:在aws的多个region中进行请求路由。


2. Eureka是Netflix的服务注册发现服务,相似于dubbo的功能。包括负载均衡和容错。


3. Hystrixhystrix是一个类库。基于命令模式,实现依赖服务的容错、降级、隔离等。在依赖多个第三方服务的时候很是有用。此外,还能够经过自定义实现dubbo的filter来给dubbo添加hystrix的特性支持。


此外,Netflix的这些开源组件统称作Netflix oss,如今很火的Spring cloud不少部分都是在这些组件基础上实现的,提供了一整套分布式系统解决方案,涵盖了作分布式微服务须要的服务发现、服务容错、负载均衡、权限控制等。固然,若是你直接选用docker的话,那么K8s自己也提供了这些东西。


以上是本人实践的一些经验。因为知识有限,不免有纰漏,敬请指出。html

相关文章
相关标签/搜索