原文地址:https://www.cnblogs.com/edisonchou/p/java_spring_cloud_foundation_sample_list.htmlhtml
本文示例基于Spring Boot 1.5.x实现,如对Spring Boot不熟悉,能够先学习个人这一篇:《Spring Boot 1.5.x 基础学习示例》。关于微服务基本概念不了解的童鞋,能够先阅读下始祖Martin Fowler的《Microservice》,本文不作介绍和描述。java
表明:Dubbo(Java)、Orleans(.Net)等node
特色:和语言绑定紧密git
表明:Spring Cloud等github
现状:适合混合式开发(例如借助Steeltoe OSS可让ASP.Net Core与Spring Cloud集成),正值当年算法
表明:Service Mesh(服务网格) => 例如Service Fabric、lstio、Linkerd、Conduit等spring
现状:在快速发展中,更新迭代比较快bootstrap
基础的云平台为微服务提供了资源能力(计算、存储和网络等),容器做为最小工做单元被Kubernetes调度和编排,Service Mesh(服务网格)管理微服务的服务通讯,最后经过API Gateway向外暴露微服务的业务接口。后端
目前,我所在的项目组已经在采用这种技术架构了,服务网格采用的是Linkerd,容器编排采用的是K8S,Spring Cloud已经没用了。But,不表明Spring Cloud没有学习的意义,对于中小型项目团队,Spring Cloud仍然是快速首选。浏览器
首先,尽管Spring Cloud带有“Cloud”这个单词,但它并非云计算解决方案,而是在Spring Boot基础之上构建的,用于快速构建分布式系统的通用模式的工具集。
其次,使用Spring Cloud开发的应用程序很是适合在Docker和PaaS(好比Pivotal Cloud Foundry)上部署,因此又叫作云原生应用(Cloud Native Application)。云原生能够简单地理解为面向云环境的软件架构。
总结 :Spring Cloud是一个基于Spring Boot实现的云原生应用开发工具,它为基于JVM的云原生应用开发中涉及的配置管理、服务发现、熔断器、智能路由、微代理、控制总线、分布式会话和集群状态管理等操做提供了一种简单的开发方式。
Spring Cloud具备以下特色:
Spring Cloud做为第二代微服务的表明性框架,已经在国内众多大中小型的公司有实际应用案例。许多公司的业务线所有拥抱Spring Cloud,部分公司选择部分拥抱Spring Cloud。例如,拍拍贷资深架构师杨波老师就根据本身的实际经验以及对Spring Cloud的深刻调研,并结合国内一线互联网大厂的开源项目应用实践结果,认为Spring Cloud技术栈中的有些组件离生产级开发尚有必定距离,最后提出了一个可供中小团队参考的微服务架构技术栈,又被称为“中国特点的微服务架构技术栈1.0”:
上图中涉及到的组件,这里不作具体介绍,有兴趣的童鞋能够浏览波波老师的这篇文章:《一个可供中小团队参考的微服务架构技术栈》。
备注:下面资料都是咱们项目组新同事以及老同事(.Net技术背景)所采用的学习资料,并不保证适合于全部人。本示例主要也主要是基于下面的资料而写的sample code。
(1)周立:《Spring Cloud与Docker 微服务架构实战》
(2)程序猿DD:《Spring Cloud 微服务实战》、《Spring Cloud基础教程(Dalston版本)(强力推荐)》
(3)纯洁的微笑,《Spring Cloud系列文章》
示例地址:https://github.com/EdisonChou/EDC.SpringCloud.Samples
此部分示例位于:part1_service-register-discovery
此部分示例主要演示了如何基于Eureka实现服务的注册与发现,其中包括两个版本:
① 单节点版本 (开发环境调试用) => 位于eureka-service-sn (sn表明single node)项目内
这里须要注意的地方是:在开发环境须要关闭Eureka的自我保护机制,否则你没法轻易看到服务移除的效果,须要在application.yml中以下设置:
eureka: server: enableSelfPreservation: false # 本地调试环境下关闭自我保护机制
这是由于Eureka考虑到生产环境中可能存在的网络分区故障,会致使微服务与Eureka Server之间没法正常通讯。它的架构哲学是宁肯同时保留全部微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。
关于自我保护机制,更多内容能够参考:《Spring Cloud Eureka全解之自我保护机制》
② HA多节点版本 (部署/生产环境用) => 位于eureka-service-ha-1 & eureka-service-ha-2这两个项目内
此版本须要注意的是两个节点的application.yml保持一致,但因为其中使用了peer1和peer2的hostname,在本地开发环境须要给Windows(我假设你使用的是Windows系统)设置hosts文件以下:
127.0.0.1 peer1 peer2
扩展:除了Eureka以外,还能够选择通用型较强的Consul,关于Consul的基本概念与服务端的安装配置能够看看个人这一篇《.Net Core微服务之基于Consul实现服务注册于发现》了解一下。最后,不得不说,Spring Boot 和 Spring Cloud中核心组件封装的注解真的是太强大了,不少操做一个注解直接搞定,无须过多的coding。
此部分示例位于:part2_client-load-balance
此部分示例主要演示了如何基于Ribbon实现客户端的负载均衡,建议启动方式:先启动Eureka,再启动UserService和MovieService。经过访问MovieService的API接口 /log-instance 进行日志查看,测试结果以下图所示:
从上图能够看出,经过客户端的负载均衡算法,依次访问了不一样的服务节点。
此部分示例位于:part3_feign
此部分示例主要演示了基于Feign如何实现声明式调用,包括如下内容:
(1)基本整合Feign进行单参数与多参数的请求:位于movie-service这个项目内
须要注意的就是别忘了在启动类加上@EnableFeignClients注解
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients // 要使用Feign,须要加上此注解 public class MovieServiceApplication { public static void main(String[] args) { SpringApplication.run(MovieServiceApplication.class, args); } }
(2)自定义Feign配置的使用:位于movie-service-feign-customizing这个项目内
下面的Feign接口就使用了自定义的配置类FeignConfiguration。
@FeignClient(name = "user-service", configuration = FeignConfiguration.class) public interface UserFeignClient { /** * 使用feign自带的注解@RequestLine * @see https://github.com/OpenFeign/feign * @param id 用户id * @return 用户信息 */ @RequestLine("GET /{id}") User findById(@Param("id") Long id); }
(3)Feign的日志的使用:位于movie-service-feign-logging这个项目内
须要注意的是:Feign虽然提供了logger,可是其日志打印只会对DEBUG级别作出响应。日志级别一共有4种类型,以下所示:
Logger.Level 可选值:
* NONE: 不记录任何日志(默认值)
* BASIC: 仅记录请求方法、URL、响应状态码以及执行时间
* HEADERS: 记录BASIC级别的基础之上,记录请求和响应的header
* FULL: 记录请求和响应的header,body和元数据
要输出日志打印,application.yml内要设置DEBUG级别:
logging: level: # 将Feign接口的日志级别设置为DEBUG,由于Feign的Logger.Level只针对DEBUG作出响应 com.mbps.cd.movieservice.feign.UserFeignClient: DEBUG
最后,针对FULL级别的日志打印效果以下图所示:
此部分示例位于:part4_hystrix
此部分示例主要演示如何基于Hystrix实现容错处理,主要包括如下内容:
(1)通用方式整合Hystrix:此示例位于movie-service项目中
针对普通的方法,只需加上HystrixCommand注解及定义回退方法便可,例如:
@HystrixCommand(fallbackMethod = "findByIdFallback") @GetMapping(value = "/user/{id}") public User findById(@PathVariable Long id) { return restTemplate.getForObject("http://user-service/" + id, User.class); } public User findByIdFallback(Long id){ User user = new User(); user.setId(-1L); user.setUsername("Default User"); return user; }
(2)Feign使用Hystrix:此示例位于movie-service-feign-hystrix项目中
针对Feign,它是以接口形式工做的,好在Spring Cloud已默认为Feign整合了Hystrix,不过默认是关闭的,须要手动在配置文件中开启:
feign: hystrix: enabled: true
在以前的版本(Dalston以前的版本)中是默认开启的,至于为什么要改成默认禁用,能够看看这里:https://github.com/spring-cloud/spring-cloud-netflix/issues/1277
而后直接在FeignClient注解中加入fallback属性便可,例以下面所示:
@FeignClient(name = "user-service", fallback = FeignClientFallback.class) public interface UserFeignClient { @GetMapping(value = "/{id}") User findById(@PathVariable("id") Long id); } @Component class FeignClientFallback implements UserFeignClient{ @Override public User findById(Long id) { User user = new User(); user.setId(-1L); user.setUsername("Default User"); return user; } }
若是想要在Feign发生回退时可以留下日志供查看回退缘由,那么可使用FallbackFactory,示例项目:movie-service-feign-fallback-factory.
当发生回退时,日志输出信息以下:
除此以外,关于Hystrix部分,还有监控的主题,这里因为我所在的项目组的技术架构中不会涉及到,也就没有弄,有兴趣的童鞋能够关注一下Hystrix自带的监控以及基于Turbine的聚合监控。参考文章:《Hystrix监控面板(Dalston版)》与《Hystrix监控数据聚合》。
此部分示例位于:part5_zuul
此部分示例主要演示如何基于Zuul实现API网关,主要包括如下内容:
(1)整合Zuul编写API网关:位于zuul-service项目中
能够测试验证的内容:
对于路由端点,须要改一下如下配置,才能正常显示路由端点信息,不然会报401的错误:
management: security: enabled: false # 默认为true,改成false以即可以看到routes
(2)Zuul的过滤器:主要位于zuul-service-filter这个项目中
对于Zuul的请求声明周期来讲,一共有4种标准过滤器类型:
此示例中演示了PRE类型的过滤器,部分场景下,想要禁用部分过滤器,只须要在配置文件中设置便可,例如这里禁用PreRequestLogFilter过滤器:
(3)Zuul的容错与回退:主要位于zuul-service-fallback这个项目中
Zuul自身就带有Hystrix,可是它监控的粒度是微服务级别,而不是某个API,当某个API不可用时,会统一抛500错误码的异常页。咱们能够为Zuul添加回退,以实现更友好的返回信息。实现也很简单,只须要实现FallbackProvider接口便可。这里要注意的是,对于Edgware以前的版本(即Dalston及更低版本)须要实现的是ZuulFallbackProvider接口,而Edgware及以后的版本要实现的是FallbackProvider接口。由于FallbackProvider是ZuulFallbackProvider的子接口,而它的好处就是多了一个接口能够获取可能形成回退的缘由,具体能够参考这一篇文章:《Spring Cloud Edgware新特性之八:Zuul回退的改进》。下面是本示例中访问user-service接口(user-service被我手动关闭)后的返回结果:
(4)Zuul的高可用架构
生产环境中通常都须要部署高可用的Zuul以免单点故障,实际开发中有两种状况:
① Zuul的客户端也注册到了Eureka Server上(好比:MVC App, SPA 等)
此时Zuul的高可用和其余微服务没区别,都是借助Eureka和Ribbon来实现负载均衡。
② Zuul的客户端未注册到Eureka Server上(好比手机App端等)
现实中这种场景或许更常见,此时须要借助一个额外的负载均衡器来实现Zuul的高可用,好比:Nginx、HAProxy以及F5等。
更多Zuul高可用的内容,能够浏览周立老师的这一篇:《Zuul的高可用》
(5)使用Zuul聚合微服务:此示例位于zuul-service-aggregation项目中
许多场景下可能一个外部请求要查询Zuul后端的多个服务,这时可使用Zuul来聚合服务请求,即只需请求一次,由Zuul来请求各个服务,而后组织好数据发送给客户端(好比App客户端)。示例中主要基于RxJava与Zuul来结合实现的微服务请求的聚合。
Spring Cloud Config为分布式系统外部化配置提供了服务端和客户端的支持,包括Config Server和Config Client两部分,其架构图以下图所示:
其中,各个微服务在启动时会请求Config Server以获取所须要的配置属性,而后缓存这些属性以提升性能,以下图所示:
此部分示例位于:part6_config
此部分示例主要演示如何基于Spring Cloud Config实现统一配置中心,主要包括如下内容:
(1)基本的Config Server与Config Client编写:此示例位于config-service与config-client中
此示例须要用到一些已放到git的配置文件,这里我已将其放到了github方便你们能够直接拿来测试用,仓库地址为:https://github.com/EdisonChou/EDC.SpringCloud.Samples.Config
端点与配置文件的映射规则以下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
其中,application: 表示微服务的虚拟主机名,即配置的spring.application.name
profile: 表示当前的环境,dev, test or production?
label: 表示git仓库分支,master or relase or others repository name? 默认是master
项目中,config-service的配置文件以下:
启动顺序:先启动config-server,再启动config-client,由于config-client在启动时就回去config-server获取配置,若是这时config-server未启动则会报错。
这里须要注意的就是在config-client中,对于spring cloud config的配置应该放在bootstrap.yml中而不是application.yml中,不然会不起做用。这里涉及到一个spring cloud的“引导上下文”的概念,能够参考这篇《深刻理解Spring Cloud引导上下文》来了解一下。
(2)使用/refresh端点手动刷新配置:仍然位于config-client项目中
要想在运行期间刷新配置,须要两点改造:加上@RefreshScope注解
@RestController @RefreshScope // @RefreshScope注解不能少,不然即便调用/refresh,配置也不会刷新 public class ConfigClientController { @Value("${profile}") private String profile; @GetMapping("/profile") public String hello(){ return this.profile; } }
此外,针对Spring Boot 1.5.x,还须要给config-client端关闭安全认证,不然没法正常refresh:
management: security: enabled: false
以后,就能够经过对config-client发起POST请求刷新配置了:
不过,若是全部微服务都须要手动刷新配置,工做量会很大。因此,在实际环境中,通常会实现配置的自动刷新。
(3)使用Spring Cloud Bus自动刷新配置:此示例位于config-server-cloud-bus与config-client-cloud-bus项目中
此示例使用到的架构以下图所示,它将Config Server加入消息总线之中,并使用Config Server的/bus/refersh端点来实现配置的刷新。这样,各个微服务只须要关注自身的业务逻辑,而无需再本身手动刷新配置。
Tip:Spring Cloud Bus基于轻量级地消息代理(例如RabbitMQ、Kafka等)链接分布式系统的节点,就能够经过广播的方式来传播状态的更改(例如配置的更新)或者其余的管理指令。咱们能够将Spring Cloud Bus想象成一个分布式的Spring Boot Actuator。
运行顺序:先启动config-service-cloud-bus,再启动两个config-client-cloud-bus(第一个默认端口8081,第二个端口改成8082),修改github中sampleservice-foo-dev.properties中的profile值后commit & push,而后POST请求config-service-cloud-bus的/bus/refersh端点,最后再次访问两个client的/profile端点进行验证。
若是部分场景想要知道Spring Cloud Bus事件传播的细节,能够经过如下设置来跟踪事件总线:
spring: cloud: bus: trace: enabled: true # 开启cloud bus跟踪
(4)与Eureka的配合使用:此示例位于config-service-eureka与config-client-eureka两个项目中
(5)Config Server的高可用:涉及到Git仓库的高可用、RabbitMQ的高可用以及Config Server自身的高可用。
对于Git仓库的高可用,第三方Git仓库相似于GitHub等自己已经实现了高可用,而针对自建Git仓库如GitLab,能够参考GitLab官方文档搭建高可用:https://about.gitlab.com/high-availability/
对于Config Server自身的高可用,也能够分为未注册到Eureka和注册到Eureka两种情形,具体能够参考Zuul的高可用的架构图。
此外,对于配置内容的加密,此示例没有涉及,它依赖于JCE(Java Cryptography Extension),能够参考这一篇《Spring Cloud配置文件加密》了解一下。
扩展:关于统一配置中心,还能够选择更好用的Apollo(携程的开源项目),能够看看个人这一篇《.Net Core微服务之基于Apollo实现统一配置中心》了解一下。
首先,值得一提的是Spring Cloud Sleuth大量借用了Google Dapper,Twitter Zipkin和Apache HTrace的设计,咱们得了解一些术语,例如:span、trace、annotation等,详细能够参考这篇《Spring Cloud系列之分布式链路监控Spring Cloud Sleuth》。
此示例位于:part7_sleuth
此部分示例主要演示如何基于Spring Cloud Sleuth实现分布式链路监控,主要包括如下内容:
(1)基础整合Spring Cloud Sleuth:位于user-service-trace与movie-service-trace项目中,主要查看控制台输出日志
(2)Spring Cloud Sleuth与Zipkin的配合使用:位于zipkin-service-server、user-service-trace-zipkin与movie-service-trace-zipkin三个项目中
Zipkin是Twitter开源的分布式跟踪系统,基于Dapper论文设计而来,主要功能是收集系统的时序数据,从而追踪微服务架构的系统延时问题,此外还提供了一个很是友好的界面来帮助追踪分析数据。
下图是一个接入Zipkin以后的服务调用简易流程图:
运行顺序:首先运行zipkin-service-server,其次运行user-service-zipkin与movie-service-zipkin,而后访问http://localhost:8010/user/1获得数据结果,最后访问zipkin server首页,填入起始时间、结束时间等筛选条件后,点击Find a trace按钮,能够看到trace列表,以下图所示:
点击“依赖分析”,能够获得下图,有助于咱们分析依赖关系:
须要注意的是,在开发调试时,由于默认的采样百分比是10%,Sleuth会忽略大量span,所以咱们能够在开发环境将其设置为100%:
spring: sleuth: sampler: # 指定需采样的请求的百分比,默认是0.1(即10%),这里方便查看设为100%(实际环境不要这样设置) percentage: 1.0
(3)使用RabbitMQ收集数据:此示例位于zipkin-service-server-stream与user-service-trace-zipkin-stream两个项目中
此外,Spring Cloud Sleuth还能够与ELK配合使用,不过此示例没有涉及,感兴趣的朋友能够参考这一篇《Spring Cloud Sleuth与ELK集成》。固然,示例中的跟踪数据都是存放到内存中,可是跟踪数据仍是建议存放到ElasticSearch中,生产环境切莫只存储到内存中。
IDE => Intellij Idea Community 2018
(PS: 若是是.Net程序猿背景,强烈建议更改快捷键与Visual Studio保持一致,这样能加快开发效率,如不了解如何修改,能够参考邹琼俊《从.Net到Java - Idea and Start Spring Boot》)
Plugin => 阿里巴巴代码规约