Spring Cloud 微服务及相关技术总结

    微服务,分布式架构。

    如果项目体量较大,比如大型电商项目,可以拆分出多个子模块比如处理商品、订单、报表、活动等,各个模块负责各自的业务,解耦合,对开发、维护都有意义,就可以引入微服务架构了。微服务后,各服务之间的影响有效降低。试想一个大项目完全用一个工程去做,体量过于臃肿,或者以通过维护接口连接的方式去实现,是相当冗余的事情。

    还有一种情形是,有些模块、组件在多个项目中有共通性,高复用性,那完全可以抽离出来形成服务模式,有效的提高了产出。
    公司组织研究开发微服务架构Spring Cloud,着手各大项目的云化。
Spring Cloud是基于Spring Boot实现的微服务架构。
我们从搭建springboot工程开始,组建各个小分队研究各个模块:分别实现了:

1、使用GIT,GIT的好处代码的保护(本机与远端)及实现开发分支化,很关键的一点是spring cloud对git有着很好的集成,尤其是在spring cloud config配置集中化环节。

2、SpringBoot工程 。在structs工程,每写一个请求url还得配置一次,简直繁琐的XML配置,没用spring mvc \boot 那你已经落伍很久了。spring boot 的出发点是配置简约化,使大家把精力更多放在业务实现上。
plat\web层:controller\service\jsp&freemaker ; 

service层:evt\controller\service\dao(mapper、provider)\myBatis&hibernate。

3、基于Swagger接口服务。在接口成做相应的配置即可,在swagger 页面中,自动呈现出具有rest风格的api文档,方便调试。而且也对RestFul风格有很好的体现。java 接口实现RestFul(表现层、资源统一),请求参格式包括path、query、body等等。使用Http那一套请求规范,请求资源GET,创建资源POST,修改资源PUT,删除DELETE,还有HEAD|OPTIONS等,而且响应标识使用标准的HTTPStatus,如请求ok 200、创建成功201,异常400等,数据格式使用JSON对前后端解析都方便。

4、服务治理中心Eurka 负责服务注册与发现。服务治理应该是微服务的核心功能点了,每个微服务即是服务提供方也是服务调用方,必须要有一个集中管理的地方,那么在spring cloud 中 这个功能由Eurka来完成,像阿里Dubbo里的服务治理,用了ZoonKepper。但无论是spirng cloud 还是 dubbo,解决的东西是相同的。我打个比喻:动物园里有老虎、狮子、狗熊等等,那么这里的动物园就是服务治理中心,老虎、狮子、狗熊就是各个独立的微服务了。

推荐Eurka相关知识地址:http://geek.csdn.net/news/detail/130223

5、资源中心,集中管理js\css,将静态资源统一管理,必须解决跨域问题。大型网站都有自己的静态资源服务器的,用nginx做静态资源服务器是一个很好的选择,只是不便于开发,所以我们用一个boot工程来做这个事情,有利有弊。

6、spring-cloud-config配置集中化的实现,建立 confgBus 工程,各微服务通过configbus拉取配置信息,实现配置集中管理。用一个git工程专门存放配置文件,spring-cloud-config与git完美配合。

关于配置集中化,很多人在思考能否做到静默修改配置文件,也就是修改配置文件不重启服务就能生效,这是一个很有意义的问题。

7、spring-cloud-ribbon 负载均衡-RestTemplate。比如我有一个服务部署了2个节点,在服务治理中心是会有2个实例的,那么服务调用方是调用那个实例呢,利用ribbon,底层是轮寻?ip Hash?最小连接数?可以去深究,但这个框架已经帮我们考虑好了,服务调用方只要通过服务治理纵向调用服务即可。

8、引入Redis、Memcached 缓存技术实现分布式架构session共享、解决高并发业务。缓存,本身就是常态技能,为了解决关系型数据库性能问题,这类key-value型数据库 响应快 性能高,spring-cloud对redis有不错的封装集成,使用起来很方便。

redis其对数据结构string list set hash等有很好的支持,还有就是RDB、AOF的支持等,优越于memcached。

9、引入RMQ,实现消息队列。类似于redis,spring-cloud对mq也有不错的封装集成,使用起来也很方便。什么样的场景要用消息中间件,MQ也好,KafKa也好,都有消息生产者与消息消费者。一般使用在数据后置处理的场景,也就是说在大量数据信息无法在瞬时处理时,可以将这些数据发送到消息件里,再通过消费者缓存消费的方式处理数据。为了响应快,我们在很多场景下用了Redis等缓存,基于内存操作的redis解决了数据处理的快速性,而数据库的持久化是快不得的,所以通过消息缓存,异步持久化。

10、引入ZoonKepper、Kafka、ELK(elasticsearch、logstash、kibana)、MogoDB实现数据监控、日志采集。

消息队列Kafka,基于主题topic形式,建立消息监听器。相较MQ而言,Kafka解决的点是大数据量的消息。Kafka集群由Zoonkepper来管理。而开源的ELK技术,对于大体量日志有很好的支持,基于文档型ES数据库,数据量级为PB,并且elk的核心解决的即时日志存储于搜索。

11、引入oauth2.0,tocken机制,实现接口鉴权。对于接口的调用,可以限流,也就是设置一个固定大小的请求队列,请求时判断限流队列是否已满,已满则提示等待,未满则进队,消费完则出队。在有限资源的情况下,缓冲服务器压力。

12、spring-cloud-zuul实现网关appGateWay 。为什么要用网关,这里的场景是外部调用内部的接口,微服务接口是通过服务治理中心来治理的,所有消费者都是从治理中心去找实例,至于请求怎么分配,这个事情spring cloud 的eurka已经为我们处理了。外部请求方通过网关先走服务治理中心这扇门,进去后才能找到对应的接口。

13、使用Docker、容器实现项目部署、多节点部署,使用CICD \Jekins实现项目自动化构建。小项目java -jar直接跑,不一定非得docker。docker可以扩容,在不同场景要求创建不同数量的容器实例,传统方式自然是做不到的。

    关于spring cloud学习,推荐一个人:翟永超。我很多知识都是阅读了他的《SpringCloud微服务实战》,这本书对SpringCloud体系有较详细的论述。翟永超目前好像任职于永辉,可以访问他的主页 http://blog.didispace.com/aboutme/。在微服务-spring cloud领域,个人认为他已经是先驱型人物。
    目前国内的微服务架构即阿里的Dubbo,相比于Spring Cloud而言,Spring Cloud背后是Spring Source,社区活活跃度自然占优。Dubbo主要是实现了服务治理及服务调用,对于微服务体系其他实现诸如配置集中化需要引入其他开源技术。而Spring Cloud 体系较为完善,对于想上手微服务的朋友们 建议从Spring Cloud入手。Dubbo服务治理必须用Zookeeper,如果你用了spring cloud再去用Dubbo,把dubbo从github下下来,用tomcat去跑dubbo项目,再启动windows版的zookeeper。你会发现还是spring cloud +eurka比较干净,毕竟已经是封装完美了。

以下是Dubbo与Spring Cloud的架构体系对比:
Spring Cloud 微服务及相关技术总结_第1张图片

苏槐的文章“快速体验微服务架构”,比较全面的展示了微服务架构的面貌,这里做一个提炼,收藏并分享给大家。
       相对于“完美”的微服务架构方案,微服务架构简单模式可以暂且不用关注保障数据一致性的分布式事务技术、方便程序包在环境间(开发、测试、生产)迁移的配置中心组件、监控 API 调用情况的调用链组件、避免系统超载的断路器组件、方便 API 管理和测试的 API 文档框架、Zookeeper、Redis,以及各种 MQ。只需要关注常常谈到的 注册中心、服务发现、负载均衡 和 服务网关 即可。
使用微服务简单模式进行开发的四个步骤:
1、沿用组织中现有的技术体系开发单一职责的微服务。
2、服务提供方将地址信息注册到注册中心,调用方将服务地址从注册中心拉下来。
3、通过门户后端(服务网关)将微服务 API 暴露给门户和移动 APP。
4、将管理端模块集成到统一的操作界面上。 
为了实现以上 4 点,相对应的就是下面必需掌握的基础技术(必需的组件)。
注册中心、服务发现、负载均衡:对应上边第一步与第二步
服务网关:对应上边第三步
管理端集成框架:对应上边第四步
注册中心、服务发现、负载均衡
      和单体架构不同,微服务架构是由一系列职责单一的细粒度服务构成的 分布式网状结构,服务之间通过轻量机制进行通信,这时候必然引入一个 服务注册发现 问题,也就是说服务提供方要将自己的服务地址注册到某个地方(服务注册中心, Service Registry Center),服务的调用方可以从服务注册中心找到需要调用的服务的地址(服务发现,Service Discovery)。同时,服务提供方一般以集群方式提供服务,也就引入了 负载均衡 的需求。
根据负载均衡(Load Balancer,简称 LB)所在位置的不同,目前主要的服务注册、发现和负载均衡方案有三种:
a、集中式 LB 方案
第一种是集中式 LB 方案,在服务消费者和服务提供者之间有一个独立的 LB,LB 通常是专门的硬件设备如 F5,或者基于软件如 LVS,HAproxy 等实现。服务调用者调用服务时,向 LB 发起请求,LB 再根据一定的策略(比如轮询、随机、最小响应时间、最小并发数等等)将请求路由到指定的服务。这个方案的最大问题是:调用者和提供者之间增加了一跳,LB 也最有可能成为整个系统的瓶颈。
b、进程内 LB 方案
第二种是进程内 LB 方案,针对集中式 LB 的不足,进程内 LB 方案将 LB 的功能以库的形式集成到服务消费方进程里头,该方案也被称为软负载 (Soft Load Balancing) 或者客户端负载方案。
 其原理是:服务提供者将自身的地址发送到服务注册中心,同时定时发送心跳给注册中心,注册中心按心跳情况判断是否将此节点从注册表中摘除。服务提供者调用服务时,先从注册中心拉取服务注册信息,然后根据一定的策略去调用服务节点。
 这种情况下,即使注册中心宕机,调用方也可以根据内存中已经拉到的服务地址将请求路由到正确的服务上去。这个方案的最大问题是:服务调用者可能需要集成注册中心的客户端,即将来注册中心服务端升级,可能会需要升级注册中心客户端。
c、主机独立 LB 进程方案
 第三种是主机独立 LB 进程方案,该方案是针对第二种方案的不足而提出的一种折中方案,原理和第二种方案基本类似,不同之处是,他将 LB 和服务发现功能从进程内移出来,变成主机上的一个独立进程,主机上的一个或者多个服务要访问目标服务时,他们都通过同一主机上的独立 LB 进程做服务发现和负载均衡。该方案的典型案例是 Airbnb 的 SmartStack 服务发现框架。这个方案的最大问题是:部署和运维比较麻烦。
 当下,随着 Netflix 的微服务方案和 Spring Cloud 的兴起与成熟,第二个方案 成为我们的首选。我们推荐使用 Eureka 做服务注册中心,Ribbon 做客户端服务发现和负载均衡。
 这个选择的最大好处是 简单 + 实用 + 可控,不用引入额外的 Zookeeper、Etcd 做注册中心,部署和运维也都比较简单。从代码上来说,使用起来也非常简单。
 只是,需要注意的是,这种方案一般是用来做 局域网内 的负载均衡,如果要为开放到互联网的服务做负载均衡,可以使用 Nginx Upstream 来做。
 下面是 Eureka 最重要的几个参数配置,从这些参数也可以大概看看 Eureka 是如何工作的。
由于 Eureka 的注册及过期机制,服务从启动到完全可用需要近 2 分钟的时间,所以,为了提高开发及测试环境中的发版速度,我们改了以下几个参数。生产时,一定要改回去。
Eureka 注册中心的界面如下:
详细信息可参考https://github.com/Netflix/eureka和https://github.com/Netflix/ribbon。
 服务网关
 通常,一个大系统里会有很多职责单一的微服务,如果门户系统或移动 APP 来调用这些微服务的 API 时,至少要做好两件事:
由统一的入口来调用微服务的 API
API 鉴权
 这就需要一个 服务网关。2015 年,我们使用 Rest Template + Ribbon 做了一个简单的 API 网关。原理就是当 API 网关接到请求 /service1/api1.do 时,将请求转发到 service1 对应的微服务的 api1 接口。
 后来,发现我们实现的功能,Spring Cloud Zuul 都有比较好的实现,也就切换到 Zuul 上面去了。Zuul 是 Netflix 基于 Java 开发的服务端 API 网关和负载均衡器。
 除此之外,Zuul 还可以对过滤器进行动态的加载、编译、运行。最令人吃惊的是,Zuul 的转发性能据说和 Nginx 差不多。详细信息可参考https://github.com/Netflix/zuul。
总的来说,一般情况下,API 网关(可以称为门户后端)用来进行反向代理、权限认证、数据剪裁、数据聚合等。
 管理端集成框架
 掌握注册中心、服务发现、负载均衡和服务网关技术后,微服务已经可以为门户系统和移动 APP 提供可靠服务。但是,给后台运营人员使用的管理端是怎么实现的呢?
由于后端运营系统的压力不大,我们可以通过 CAS 和 UPMS(UPMS 是我们团队研发的契合微服务架构的用户及权限管理系统,我们将分享到青柳云官网,欢迎关注)将单独开发的微服务整合起来。
三步集成一个微服务的基本过程就是:
 在微服务中引入基于 Spring Boot 的 security starter,starter 里包含了系统的顶端 Banner 和左侧菜单。
将微服务的访问地址注册到 UPMS 中,这个地址作为此微服务的入口菜单(一级菜单)。
 在 UPMS 中配置微服务的功能菜单及角色权限信息。用户从浏览器打开一个微服务的时候,security starter 会调用 UPMS 的 API 拉取所有的微服务清单(一级菜单)和当前微服务的功能清单(二级菜单),并将当前微服务的页面在内容区展现给用户。
应用架构图:
 UPMS 截图,橙色部分由 UPMS 框架提供,红色框为微服务的页面:
 UPMS 通过“模块”功能接入新的微服务:
所以,到最后,一个简单模式的基于微服务架构的系统就可以长成这样:
至此,基本的微服务架构已经搭建起来。下面来聊聊怎么解决微服务运维的问题。
      微服务架构的运维问题,主要是相对于单体架构来说的。因为实施微服务架构后,整个系统的模块一下子比原来多了很多,模块变多后,部署和维护的工作量都会变大。所以,解决运维难的问题,可以先从 自动化 的角度来解决。
 更进一步,如果希望更好地发挥微服务架构的优势,规避缺点,则建议准备一个可靠的基础设施,包含自动构建、自动部署、日志中心、健康检查、性能监控等功能。
否则,很有可能会因为微服务架构的缺点导致我们的团队丧失对微服务架构的信心,从而回到单体架构的老路上去。工欲善其事,必先利其器,这一点真的很重要。
 持续集成
 单体应用被微服务化后,很有可能从原来的一个程序包分成了 10 个、20 个甚至更多的程序包。那么,我们首先遇到的麻烦就是部署工作直接扩大了 10 - 20 倍。这时,持续集成的方法和工具就成了实施微服务架构的前提条件。我们在实践过程中,利用基于 Docker 的容器服务平台自动部署整个系统的微服务。其过程如下图:
如果没有微服务支撑平台,也可以通过 Shell 脚本的形式来调用 Jenkins API 和 Docker API。
主要过程是:
 调用 Jenkins 命令从代码仓库拉取代码,并打包代码。
 调用 Docker /build 和 /images/push 命令构建镜像,并将镜像推送到私有镜像仓库中。
 调用 Docker /containers/create 和 /containers/start 命令创建并启动容器。
 配置中心
 在开发 / 测试环境上,程序包已经被打包成 Docker 镜像,如果能将通过测试的镜像直接推到生产环境,可以直接省去为生产环境而重复进行的打包部署工作,岂不是很美?
如果需要达到这个效果,就需要将程序包打包成具有环境无关性,也就是说,在程序包里是不可以有环境相关的配置信息的,这也就引入了 配置中心 组件。
 这个组件非常简单,只是根据项目代号、环境代号和微服务代号来获取微服务所需要的键值对。例如:
ProjectA_PRODUCTION_MicroService1_jdbc.connection.url。
 使用配置中心还有一个很重要的附加价值,那就是可以做到不同环境的配置信息可以由不同的人来管理,加强了生产环境的配置信息的安全性,例如数据库帐号和密码。
 这个模块也有一些开源的项目可以参考,例如百度 disconf,Spring Cloud Config。而我们自己发杨了重复造轮子的精神,开发了一个配置中心微服务,以方便地与上面提到的 UPMS 进行整合。
注意:这一组件并不是微服务架构简单模式的必需组件,只是建议使用。
 监控告警
 单体应用被微服务化后,一个单体应用被拆成了很多个微服务,系统的健康巡检、性能监控、业务指标健康、文件备份监控、数据库备份监控、定时任务执行情况监控都变得困难。
所以,为了让运维的同学能生活得踏实点,最好也能把监控平台给建了。如果希望快速搭建监控平台,可以考虑 Nagios,Zabbix。如果希望扩展性、可定制性更好,可以考虑使用以下组件搭建:
Collectd 是一款主机、数据库、网络、存储指标采集器。GitHub 上 1653 个 Star。
 Metrics 是一款牛逼的 JVM 指标采集器,提供了很多模块可以为第三方库或者应用提供辅助统计信息, 比如 Jetty, Logback,Log4j,Apache HttpClient,Ehcache,JDBI,Jersey,它还可以将度量数据发送给 Ganglia 和 Graphite 以提供图形化的监控。GitHub 上 5000+ 个 Star。
CAdvisor 是一款 Docker 容器指标采集器,Google 出品。GitHub 上 6000 个 Star。
Grafana 是一款非常精美的开源仪表盘工具,支持 Graphite,InfluxDB ,MySQL 和 OpenTSDB 等多种数据源。GitHub 上 17000 个 Star。
 InfluxDB 是一款优秀的开源分布式时序数据库,目前在时序数据中排名第一,它的特性中,RETENTION POLICY 可以自动地清除不需要的历史数据,很实用。GitHub 上 11175 个 Star。
除了以上模块,我们还开发了一个模块,用来探测应用程序的健康情况和性能,在主机、程序健康情况、程序性能等各种指标出现异常时,发送警报给运维人员。
 在这篇文章结束的时候,我们可以回过头来看看,我们只需要在开发层面理解了注册中心、服务发现、负载均衡、服务网关和管理端集成框架,在运维层面准备好持续集成工具、配置中心和监控告警工具,就可以很容易地落地微服务架构,享受微服务架构带来的精彩。
 Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务。Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring Cloud的服务发现功能。

15、使用Nginx实现反向代理。


你可能感兴趣的:(springBoot,微服务,Spring,Cloud)