Spring-Cloud微服务实战

    说到微服务,相信大家一定不陌生,Duobbo、Spring Cloud 都是目前很流行的微服务框架,Spring Cloud 对于中小型互联网公司来说是一种福音,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,使用 Spring Cloud 一站式解决方案能在从容应对业务发展的同时大大减少开发成本,但是在技术选型和实际生产应用中仍然会碰到很多的问题。所以结合我司 VPGAME 在交易、库存、消息、赛事、Dota2 数据服务 等核心业务场景的实际落地经验,以及国内外一线互联网公司在微服务的开源实践,总结出一些 Spring Cloud 微服务实践和使用过程出现的问题,希望能够为大家解决一些疑惑。


1. 服务注册与发现
    - 服务注册:
    Spring Cloud 支持Consul、Zookeeper、Etcd、Euerka 等多种注册中心,这里主要讲一下 Zookeeper 和 Euerka 选择时的一些考虑。著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性),由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。ZooKeeper基于CP,不保证高可用,如果 ZooKeeper 正在选主,或者 Zookeeper 集群中半数以上机器不可用,那么将无法获得数据。Eureka 基于AP,能保证高可用,即使所有机器都挂了,也能拿到本地缓存的数据。很显然在注册中心的场景,更关注的是服务高可用,但是我们最终选用了 Zookeeper 作为注册中心,主要有以下几点原因:

a.我们自研的服务管理中心通过修改服务权重实现了服务热更新和合理负载等功能,需要保证配置信息的强一致性

b.在实际的生产过程中服务发现都是通过内网通信,网络问题和集群半数以上机器宕机的可能性非常小,当然我们也可以参考 Euerka 的本地缓存机制来提高其可用性

    - 服务发现:

    Ribbon是客户端软负载库,内部微服务直连可以直接走 Ribbon 客户端软负载,网关上也可以部署 Ribbon,我们在生产中主要是在在网关上通过 Ribbon 来实现软负载, 这一点就不再赘述。

2. 服务网关
 
    Zuul 网关在 Netflix 经过生产级验证,在纳入 Spring Cloud 体系之后,在社区中也有众多成功的应用,微服务基础架构中网关一块的首选,我们在实践过程中通过其实现了参数签名验证、用户身份认证、动态路由(支持Java 、PHP、Go等多语言服务)、服务灰度、服务限流等功能。需要注意的主要有以下几点:

a.线程数,Ribbon 总连接数、单个路由连接数、超时时间,Hystrix 熔断条件等核心参数的配置
b.Zuul 1.0 是同步阻塞架构,依赖多线程来支持吞吐量的增长,高并发情况下因为某个服务异常容易导致雪崩,因此需要结合 Hystrix 实现服务熔断和降级。但是 Zuul 2.0 用异步非阻塞架构可以更好的解决该问题,同时2.0版本还发布了许多新特性,需要在生产中实践验证。

Spring-Cloud微服务实战

 

3. 配置中心:

   在大型分布式系统架构中,各个服务之间的配置信息管理和同步问题很快就会凸显出来,我们在最初的架构中采用的是Zookeeper 作为配置中心,当服务数量不多且部署在同一个机房的情况下方便实用。但是当服务越来越多,配置也成倍的增加,更涉及到跨机房跨可用区甚至跨洋,配置无法可视化管理、跨机房调用、配置权限透明等问题急需解决。我们当时调研了Spring Cloud Config 和 Apollo 两个开源的配置信息框架,通过调研Spring Cloud Config的功能并不能完美的应对复杂的分布式场景,也不能进行可视化管理,而携程开源的 [Apollo](https://github.com/ctripcorp/apollo/wiki) 支持完善的管理界面,支持多环境,配置变更实时生效,权限和配置审计等多种生产级功能,更适合目前在生产环境中的直接使用。

4. 服务链路监控

    在单体应用架构中,我们可以通过日志快速的进行问题分析和定位,但是在分布式微服务场景下很难简单的通过日志查看某一个请求经过网关然后调用了对应的哪些服务,以及相应的请求状态和时长,同时针对多语言和前后端分离我们在通信协议里规定一个请求从Web 和移动端发起需要在header头携带X-Request-ID 参数,同样在后续服务应用日志中都会要求添加该参数,这样每一个流入系统请求的都会有一个唯一标识,当出现问题很容易进行故障定位。当然Spring Cloud支持基于 Zipkin 的调用链监控,我们在生产中结合自研 trace 系统实现了服务的链路追踪,对于微服务场景下的问题排查有非常大的帮助:

Spring-Cloud微服务实战

 

5. 服务监控和告警

   当整个微服务系统在线上能够稳定的运行,并不代表我们就可以高枕无忧了,恰恰相反随着服务数量的不断增加,排查问题变得越来越困难,能否第一时间处理和预警,对于每个服务的监控就显得尤为重要,在服务化初期,我们采用的自研monitior-service 、Influxdb 、 Grafana实现了第一个版本的监控和告警。
   

Spring-Cloud微服务实战


   每个客户端自行将监控数据通过monitor-service保存到 influxdb ,然后通过Grafana配置相应的监控面板和告警策略。随着业务的不断增长,监控粒度和指标以及告警策略的管理,也都越来越困难,为此我们进行了第二轮的监控系统升级,架构如图:

Spring-Cloud微服务实战


另外附上我们的整体微服务分层架构,有不足之处欢迎留言一起探讨。

Spring-Cloud微服务实战


   写在结尾,以上只是整个微服务架构体系中的一部分,在分布式微服务架构中分布式锁、分布式缓存、微服务的部署和持续集成等都是非常重要的,在此就没有一一进行列举。总之我们需要保持对新技术的渴望和追求,更应该结合公司的实际情况,选择最适合的技术栈和架构。