Spring Cloud micro Services Architecture Study Notes and examples

The development of a distributed service framework

The first generation Services Framework 1.1

  Representatives: Dubbo (Java), Orleans (.Net), etc.

  Features: compact and language bindings

1.2 Second generation services frame

  Representatives: Spring Cloud, etc.

  Status: suitable for hybrid development (for example by means Steeltoe OSS allows ASP.Net Core Integration with Spring Cloud), positive year

1.3 Third Generation Services Framework

  Representatives: Service Mesh (service grid) => eg Service Fabric, lstio, Linkerd, Conduit, etc.

  Status: in its rapid development, updated faster iterations

1.4 Future (visual Soon) mainstream services architecture and technology stack

  

  Based cloud platform micro service resource capabilities (computing, storage and network, etc.), the container as the smallest unit of work Kubernetes scheduled and scheduling, Service Mesh (Grid Service) services communications managing widgets and services, and finally through the API Gateway to micro-business interface exposed outside services.

  Currently, the project team where I have been using this technology architecture, and service grid uses Linkerd, container choreography uses K8S, Spring Cloud has been useless. But, does not mean that Spring has not learned the meaning Cloud, for small and medium sized project teams, Spring Cloud is still the first choice fast .

Two, Spring Cloud Profile

2.1 Spring Cloud minimalist presentation

  

   First, although the Spring Cloud with the "Cloud" word, but it is not cloud computing solutions, but built in Spring Boot foundation for rapidly building toolset common mode of distributed systems.

   Secondly, the use of Spring Cloud is ideal for the development of applications deployed on Docker and PaaS (such as Pivotal Cloud Foundry), it is also known as native cloud applications (Cloud Native Application). Cloud native can be simply understood as a software architecture for cloud environments.

Summary  : the Spring Cloud is a cloud-based native application development tools Spring Boot achieve, and it is based on the configuration management cloud-native application development JVM is involved, service discovery, fuses, intelligent routing, micro broker, a control bus, distributed session and state of the cluster management operations provides a simple way of development.

  Spring Cloud has the following characteristics:

  • Greater than the configured convention
  • For a variety of environments
  • Hides the complexity of the components, and provides a declarative, non-XML-style configuration
  • Out of the box, Quick Start
  • Components rich, full-featured
  • ......

  Spring Cloud representative frame as the second generation micro-services, has many large and small companies in the country have practical application cases. Many of the company's business lines are all embracing Spring Cloud, some companies choose to embrace part of the Spring Cloud. For example, pat loans senior architect Bo teacher based on their practical experience and in-depth research on Spring Cloud, combined with the practical application of the results of the domestic first-tier Internet giant open-source project that Spring Cloud technology stack some components from the production level development there is a certain distance, and finally put forward a team for small micro-service architecture reference stack technology, also known as "Chinese characteristics, micro services architecture technology stack 1.0":

  

  The figure above components involved here is not specifically introduced, interested children's shoes can browse wave teacher this article: " a small team of reference for micro Services Architecture technology stack ."

2.2 Spring Cloud core subprojects

  • Spring Cloud Netflix: core components, can integrate multiple open source Netflix OSS suite includes the following components:
    • Eureka: service management components, including service registration and discovery
    • Hystrix: fault-tolerant management components to achieve a fuse
    • Ribbon: balancing client load component service invocation
    • Feign: based declarative services and Hystrix the calling component Ribbon
    • Zuul: Gateway component that provides intelligent routing, access filtering,
    • Archaius: Configuration of external components
  • Spring Cloud Config:配置管理工具,实现应用配置的外部化存储,支持客户端配置信息刷新、加密/解密配置内容等。
  • Spring Cloud Bus:事件、消息总线,用于传播集群中的状态变化或事件,以及触发后续的处理
  • Spring Cloud Security:基于spring security的安全工具包,为我们的应用程序添加安全控制
  • Spring Cloud Consul : 封装了Consul操作,Consul是一个服务发现与配置工具(与Eureka作用类似),与Docker容器可以无缝集成
  • ......

三、参考学习资料

  备注:下面资料都是我们项目组新同事以及老同事(.Net技术背景)所采用的学习资料,并不保证适合于所有人。本示例主要也主要是基于下面的资料而写的sample code。

  (1)周立:《Spring Cloud与Docker 微服务架构实战

  

  (2)程序猿DD:《Spring Cloud 微服务实战》、《Spring Cloud基础教程(Dalston版本)强力推荐)》

  

  (3)纯洁的微笑,《Spring Cloud系列文章

四、示例结构说明

4.1 示例环境版本

  • Java : JDK & JRE 1.8 8u151
  • Spring Boot : 1.5.15.RELEASE
  • Spring Cloud : Edgware.SR3 (小贴士:Spring Cloud的版本命名是以伦敦地铁站的名字来命名的)

4.2 示例地址与结构说明

  示例地址:https://github.com/EdisonChou/EDC.SpringCloud.Samples

4.2.1 服务注册与发现 - 基于Eureka

  此部分示例位于: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。  

4.2.2 客户端负载均衡 - 基于Ribbon

  此部分示例位于:part2_client-load-balance

  此部分示例主要演示了如何基于Ribbon实现客户端的负载均衡,建议启动方式:先启动Eureka,再启动UserService和MovieService。通过访问MovieService的API接口 /log-instance 进行日志查看,测试结果如下图所示:

  

  从上图可以看出,通过客户端的负载均衡算法,依次访问了不同的服务节点。

4.2.3 声明式REST调用 - 基于Feign

  此部分示例位于: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级别的日志打印效果如下图所示:

  

4.2.4 容错处理 - 基于Hystrix

  此部分示例位于: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.

View Code

  当发生回退时,日志输出信息如下:

  除此之外,关于Hystrix部分,还有监控的主题,这里由于我所在的项目组的技术架构中不会涉及到,也就没有弄,有兴趣的童鞋可以关注一下Hystrix自带的监控以及基于Turbine的聚合监控。参考文章:《Hystrix监控面板(Dalston版)》与《Hystrix监控数据聚合》。

4.2.5 API网关 - 基于Zuul

  此部分示例位于:part5_zuul

  此部分示例主要演示如何基于Zuul实现API网关,主要包括以下内容:

  (1)整合Zuul编写API网关:位于zuul-service项目中

  可以测试验证的内容:

  • 路由规则:依次启动eureka,user-service,movie-service,zuul-service,然后通过zuul访问user-service接口
  • 负载均衡:依次启动eureka,多个user-service,zuul-service,然后多次访问user-service,最后查看日志信息(两个user-service都会打印hibernate日志信息),验证是否达到负载均衡的效果。PS:Zuul内置了Ribbon来实现负载均衡。  
  • 路由端点:依次启动eureka,user-service,movie-service,zuul-service,然后浏览器访问zuul-service(http://localhost:5000/routes)可以得到路由端点信息

  对于路由端点,需要改一下以下配置,才能正常显示路由端点信息,否则会报401的错误:

management:
  security:
    enabled: false # 默认为true,改为false以便可以看到routes
  • 路由配置:示例主要演示了路由前缀、全局敏感设置以及路由规则设置
  • 大文件上传设置:针对超大文件上传(比如500M),需要在Zuul中提升超时设置
View Code

  (2)Zuul的过滤器:主要位于zuul-service-filter这个项目中

  对于Zuul的请求声明周期来说,一共有4种标准过滤器类型:

  • PRE:在请求被路由之前调用,可利用这种过滤器实现身份验证、记录调试信息等操作;
  • ROUTING:将请求路由到微服务,可利用这种过滤器用于构建发送给微服务的请求;
  • POST:在路由到微服务以后执行,可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等;
  • ERROR:在其他阶段发生错误时执行该过滤器;  

    

  此示例中演示了PRE类型的过滤器,部分场景下,想要禁用部分过滤器,只需要在配置文件中设置即可,例如这里禁用PreRequestLogFilter过滤器:

View Code

  (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来结合实现的微服务请求的聚合。

4.2.6 统一配置管理 - 基于Spring Cloud Config

  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的配置文件如下:

View Code

  启动顺序:先启动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的高可用的架构图。

  此外,对于配置内容的加密,此示例没有涉及,它依赖于JCEJava Cryptography Extension),可以参考这一篇《Spring Cloud配置文件加密》了解一下。

扩展:关于统一配置中心,还可以选择更好用的Apollo(携程的开源项目),可以看看我的这一篇《.Net Core微服务之基于Apollo实现统一配置中心》了解一下。  

4.2.7 微服务跟踪 - 基于Spring Cloud Sleuth

  首先,值得一提的是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 => 阿里巴巴代码规约

Guess you like

Origin www.cnblogs.com/newcityboy/p/12071109.html