Spring Cloud

Spring Cloud知识点

1、Spring Cloud

微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自的进程中运行,服务之间一般通过HTTPRESTful API进行通信协作。

Spring Cloud是一系列框架的有序集合,它通过Spring Boot实现各个框架的自动配置,简化开发和维护。

Spring CloudDubbo都是实现微服务的有效工具。Dubbo使用RPC通讯协议,Spring Cloud使用RESTful完成通信,Dubbo效率略高于Spring Cloud

Spring中提供了RestTemplate模板类,可用于在java代码里访问RESTful服务。

2Spring Cloud Netflix

2.1 Eureka服务治理

Eureka本质就是对各个微服务的ipport进行统一维护,在进程服务调用的时候,可以根据ServiceId从注册中心获取对应的ipport号。(当然了单看这个组件功能比较单一,但是很多组件集成在一起,它可以起一个桥梁的作用)

编写Eureka Server端:

1、导入spring-cloud-starter-netflix-eureka-server包;

2、在引导类上添加@EnableEurekaServer@EnableDiscoveryClient注解;

3、配置application.yml

必须配置项:

spring:
  application:
    name: eureka-server
server:
  port: 10086
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    fetch-registry: false
    register-with-eureka: false

4、访问http://localhost:10086即可在UI界面中查看eureka注册中心状态

编写instance

1、使用SpringBoot正常构建web项目即可;

2、在引导类上添加@EnableEurekaClient注解;

3、配置application.yml

必须配置项:

spring:
  application:
    name: eureka-client1

eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    fetch-registry: true
    register-with-eureka: true

备注:

1)使用RestTemplate对象(需要配置Bean)进行服务调用,常用方法

<T> T getForObject(String url,Class<T> ResponseType)

2)使用DiscoveryClient对象(直接注入)从Eureka server端通过注册的服务名字获取 对应服务的Instances,是个List集合

List<ServiceInstance> getInstances(String serviceId)

通过ServiceInstance对象获取对应服务的IPport

String getHost();

int getPort();

2.2 Ribbon负载均衡

RibbonNetflix提供的基于HTTPTCP的客户端负载均衡。

负载均衡:指的是当为了实现服务的高可用,可以将相同的服务部署在不同的机器上,当客户端调用该服务的时候,通过负载均衡算法选择访问其中的一台机器。

客户端负载均衡:指的是在客户端实现负载均衡算法,然后选择访问那台机器。

服务端负载均衡:指的是在服务器端实现负载均衡方法,服务器接收到访问请求之后通过负载均衡算法决定访问那天一起。

Ribbo的负载均衡策略是:当一个服务1调用一个服务2的时候,服务1已经实现了负载均衡,请求发出时已经确定访问那台服务器。

Nigin的负载均衡策略是:当客户端访问服务端的时候,请求到达服务端之后,通过负载均衡算法再决定将请求转发到那台服务器。

RibbonEureka结合,如果服务1部署在了多台服务器,然后都会注册到Eureka ServerServiceId一般注册的名字相同),当服务2调用服务1的时候,通过服务1ServiceIdEureka Server中获取,会获得同一服务的多个Instance,此时采用Ribbon进行HTTP访问的时候,内部就封装了负载均衡的算法。

Spring Cloud对负载均衡进行了很好的封装,与2.1中一样,还是使用RestTempalte对象进行HTTP访问,只需要简单的配置之后,RestTempalte对象在进行HTTP访问的时候就会自动实现负载均衡。

步骤:

2.1的基础上对Instance端进行改造:

1、spring-cloud-starter-netflix-eureka-ribbon包已经继承了ribbon不需要额外导包;

2、在配置RestTemplateBean时,加上@LoadBalanced注解;

3、RestTemplate进行服务调用的时候url格式

http://serviceId/test/demo1

备注:url中的IPport用需要调用的服务在Eureka Server中的注册ServiceId代替即可。

2.3 Feign声明式服务调用

Feign是对RestTempalte进行封装,基于接口生成动态代理对象,简化远程服务的调用。

备注:RestTemplate进行远程调用的时候,除了url不同外,调用方式完全相同,因此可以将url进行抽取出来,配置到接口中,通过接口动态生成代理对象,在使用的时候直接注入该对象,然后调用方法即可。

2.12.2的基础上:

1)导入spring-cloud-starter-openfeign包;

2)在引导类上加上@EnableFeignClients

3)编写一个接口;

备注:@FeignClient中的value值表示需要调用的服务在Eureka Server注册的ServiceId

接口的方法除了没有方法体外,与被调用的服务相同即可。

@FeignClient(value = "eureka-client1")
public interface UserFeignClient {
    @RequestMapping("/test/findById/{id}")
    public User findById(@PathVariable(value = "id") int id);
}

2.4 Hystrix熔断器

HystrixNetflix开源的延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。

雪崩:在微服务架构中,一个服务失败导致整条链路的服务都失败的情况。

Hystrix的功能:

隔离:1)线程池隔离;2)信号量隔离;

降级:当服务1需要调用服务2的时候,存在两种情况:1)服务2不存在或网络不通,此时可以在服务1实现降级处理;2)可以访问到服务2,但服务2出错了,服务2可以进行降级处理。(备注:降级处理指的是,可以写一个方法,当原本的服务出现问题的时候,调用该方法)

熔断:当某个服务在某段时间内被访问导致多次出错的时候,该服务被禁用,然后再过一段事件后,该服务半开,可以被部分请求访问,如果继续出错,则再次被禁用(过一段时间又会半开),如果出现访问正常,则该服务全开,可供访问。

限流:指的是对访问进行限制;

2.12.22.32.4的基础上:

1)导入spring-cloud-starter-netflix-hystrix包;

2)在引导类上加@EnableCircuitBreaker注解;

3)Controller中的方法添加降级方法;

在需要配置降级方法的前面加上 @HystrixCommand注解,参数值指定降级之后调用的方法,该降级方法的编写与原方法方法名和方法体不同,其他相同。

@RestController
@RequestMapping("/client1")
public class UserController {
    @Autowired
    private UserFeignClient userFeignClient;
    @RequestMapping("/findUserById/{id}")
    @HystrixCommand(fallbackMethod = "findUserById_fallback")
    public User findUserById(@PathVariable int id){
        int i = 1/0;
        User user = userFeignClient.findById(id);
        return user;
    }
    public User findUserById_fallback(int id){
        System.out.println("出错啦");
        return new User();
    }
}

3Spring Cloud GateWay

Spring Cloud GateWay网关旨在为微服务架构提供一种简单而有效的同一API路由管理方式。类似于Spring MVC中的DispatcherServlet前端控制器,前端的请求全部经由网关,然后将请求路由到需要调用的服务,这样做的好处就是,前端只需要与网关交互,降低代码的耦合性,同时还可以在网关中实现一些与服务无关的统一性的操作,譬如认证、监控、缓存、负载均衡等。

实现步骤:

1)新建一个SpringBoot项目

导入spring-cloud-starter-gateway包;

2)配置application.yml

其中routes配置的是路由规则,如果访问的uri中资源路径(除访问协议、IPpoprt后的部分),符合predicates的规则,就会将请求转发到uri(配置中的uri)配置的路径+访问的uri(浏览器要访问的uri)中的资源路径。

譬如,如果浏览器访问http://localhost:80/client1/test/demo

该路径的资源理解符合Path=/client1/**的路由规则,然后路由到http://localhost:8001/client1/test/demo,将该url的资源再返回给前端。

server:
  port: 80
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
      - id: gateway
        uri: http://localhost:8001/
        predicates:
        - Path=/client1/**

上述的路由方式属于静态路由,直接将在application.yml中直接写的是路由uri固定地址,可以将spring cloud gatewayeureka结合起来,使网关根据服务在eureka server中的ServceId找到对应的服务。

步骤:

1)在上述的基本上进行改造即可;

2)导入eureka的包;

3)在引导类上加上@EnableEurekaClient,使网关作为一个服务注册到注册中心;

4)配置application.yml文件;

uri的配置改写为lb://ServiceId

server:
  port: 80
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
      - id: gateway
        uri: lb://eureka-client2
        predicates:
        - Path=/client1/**
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    fetch-registry: true
    register-with-eureka: true

4Spring Cloud Config

Spring Cloud Config解决了在分布式场景下多环境配置文件的管理和维护。

在分布式环境中,配置文件多且存在同一服务重复发布的情况,此时修改配置文件将会特别麻烦。Spring Cloud Config可以对配置文件进行统一管理,还可以在不重启服务的情况下,更新配置文件。

可以将配置文件放在git仓库,创建一个配置中心服务端并与该git仓库进行关联,可以通过该服务查看git仓库中的配置文件信息,然后需要使用配置文件的Spring Boot项目作为配置中心的客户端,在客户端中进行配置之后,客户端在启动程序的时候会从配置中心服务端获取相应的配置文件。

配置中心服务端的实现步骤:

1)在上述代码的基础上进行;

2)使用Spring Boot创建配置中心服务端;

3)导入spring-cloud-config-server包;

4)配置application.yml文件;

uri表示配置文件放置的git仓库路径;

lable表示仓库的分支;

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/wuyiping2020/config-server.git
      label: master
server:
  port: 8888

5)配置中心服务端测试

该配置中心可以作为一个服务访问其关联到的git库中的配置文件,路径如下:

其中master表示分支,config-server.yml表示该分之下的文件名

http://localhost:8888/master/config-server.yml

配置中心客户端的实现:

1)可以在3Spring Cloud GateWay的基础上进行配置即可,也可重新创建一个Spring Boot项目;

2)导入spring-cloud-config包;

3)配置bootstrap.yml文件;

重启项目会出现如下的日志信息,表示从哪里取配置文件

git仓库中存放了config-dev.yml文件

Fetching config from server at : http://localhost:8888

Located environment: name=config, profiles=[dev], label=master, version=2c030dd27d32dfd22122cada016fbecb8a4ab8aa, state=null

spring:
  cloud:
    config:
      uri: http://localhost:8888
      name: config
      label: master
      profile: dev

4)Controller层中直接注入配置文件中写的键值对,然后再编写一个方法直接返回来测试;(config-dev.yml就写了一个键值对namefortestzhangsan,访问之后直接在页面上显示zhangsan

@RestController
@RequestMapping("/client1")
public class UserController {
    @Value("${namefortest}")
    private String name;
    @RequestMapping("/name")
    public String name(){
        return name;
    }
}

由上可知,使用Config配置中心,Spring Boot项目可以在启动的时候读取配置中心的配置文件,但是如果对配置中心的配置文件做了修改,如何将修改同步到项目中呢?

客户端配置文件的更新步骤:

1)git仓库中的配置文件修改之后,配置中心再访问的话就会是已更新的文件,但是该更新的配置文件并没有同步到配置中心客户端的项目中;

2)在配置中心的客户端引入spring-boot-actuator依赖;

3)在配置信息类上添加@RefreshScope

4)添加配置

management:
  endpoints:
    web:
      exposure:
        include: refresh

5) 使用curl工具发送POST请求即可更新配置中心客户端的配置文件

curl -X POST http://需要更新的服务的ip:port/actuator/refresh

 

6) 访问测试

Config配置中心与Eureka注册中心的结合:

1)同样的,如果配置中心服务器的地址发生变化,那么与该配置中心关联的所有客户端都需要更改ip地址,为了避免这种情况,可以将Config配置中心作为服务注册到Eureka Server

2)Config配置中心服务端,导入spring-cloud-starter-netflix-eureka-client包;

3)然后在引导类上加上@EnableEurekaClient

4)改造配置中心bootstrap.yml文件

原本eureka的配置写在application.yml中,配置中心的配置写在bootstrap.yml中,(bootstrap.yml的优先级更高),如果还是分开写,只是把config.uri改成config.discovery进行配置的话,会出现找不到config-server的报错信息,如果将eureka的配置和config server的配置写在一起,就没有报错

server:
  port: 8001
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    register-with-eureka: true
    fetch-registry: true
spring:
  application:
    name: eureka-client2
  cloud:
    config:
      name: config
      label: master
      profile: dev
      discovery:
        enabled: true
        service-id: config-server
management:
  endpoints:
    web:
      exposure:
        include: refresh

5)更新git库中的配置文件,发送POST请求更新项目的配置信息,测试是否更新;

5Spring Cloud Bus

Spring Cloud Bus消息总线是用轻量级的消息中间件,将分布式的节点连接起来,可以用于广播配置文件的更改或者服务的监控管理。关键的思想是,消息总线可以为微服务做监控,也可以实现应用程序之间相互通信。

Spring Cloud Bus可选的消息中间件可以是RabbitMQKafka

Spring Cloud Bus是与Spring Cloud Config集成使用的,需要在配置中心引入actuator的坐标,其功能是对配置中心进行监控,actuator会检测到配置文件的相关变化并暴露出refresh的埋点,当发送POST到配置中心的RabbitMQ之后,它会广播道其他的节点。

实现步骤:

1)安装并启动RabbitMQ服务;

1)4Spring Cloud Config的基础上进行改造;

2)配置中心和各个微服务引入actuatorbus-amqp坐标;

3)配置application.yml文件

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /

4)发送curl -X POST http://localhost:8888/actruator/bus-refresh

urlipport是配置中心的ip和地址。

6、Spring Cloud Stream消息驱动

Spring Cloud Stream是一个构建消息驱动微服务应用的框架。

Stream解决了开发人员无感知的使用消息中间件的问题,因为Stream对消息中间件实现了进一步的封装,对外暴露了与消息中间件交互的统一API。如果在开发过程中,消息中间件发生了改变,只需要简单的配置即可,代码并不需要修改。(类似JAVA为操作数据库提供了JDBC的统一接口,各个数据库公司提供具体实现,在编程过程中只需要面向接口即可)。

Spring Cloud Stream目前支持两种消息中间件RabbitMQKafka

Spring Cloud Stream构建的应用程序与消息中间件之间是通过绑定器Binder相关联的。绑定器对于应用程序而言可以起到隔离作用,屏蔽应用程序直接与消息中间件的直接交互,只需要面向中间件即可。

binding指的是将应用程序和Spring Cloud StreamBinder绑定在一起。

output指的是发送消息的Channel,内置Source接口;

input指的是接收消息的Channel,内置Sink接口;

消费生产者:

1)安装并启动RabbitMQ服务;

2)创建Spring Boot项目,引入spring-cloud-starter-stream-rabbit;

3)为消息生产者编写配置文件,定义binderbindings

spring:
  cloud:
    stream:
      bindings:
      binders:
        wyp_binder: #定义绑定器
          type: rabbit #定义绑定器的类型
          environment: #定义绑定器的环境信息
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
                virtual-host: /
        bindings:
          output: #channel名称
            binder: wyp_binder #指定使用哪一个绑定器
            destination: wyp_exchange #消息目的地

server:
  port: 8000

 

4)定义消息发送业务类,添加@EnableBinding(Source.class),注入MessageChannel output对象,完成下消息发送;

可以在Controller层直接注入该对象调用相关方法实现在前端访问发送消息的目的。

@Component
@EnableBinding(Source.class)
public class MessageProducer {
    @Autowired
    private MessageChannel output;
    public void sendMsg(){
        String message = "hello stream";
        output.send(MessageBuilder.withPayload(message).build());
        System.out.println("消息发送成功了。");
    }
}

消息消费者:

1)创建Spring Boot项目,引入spring-cloud-starter-stream-rabbit;

2)编写配置,定义binderbindings

spring:
  cloud:
    stream:
      bindings:
      binders:
        wyp_binder: #定义绑定器
          type: rabbit #定义绑定器的类型
          environment: #定义绑定器的环境信息
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
                virtual-host: /
        bindings:
          input: #channel名称
            binder: wyp_binder #指定使用哪一个绑定器
            destination: wyp_exchange #消息目的地
server:
  port: 9000

3)定义消息接收业务类,添加@EnableBinding(Sink.class),使用 @StreamListener(Sink.INPUT)完成消息接收。

@Component
@EnableBinding(Sink.class)
public class MessageListener {
    @StreamListener(Sink.INPUT)
    public void receiveMsg(Message message){
        System.out.println(message.getPayload());
    }
}

7、Spring Cloud SleuthZipkin

Spring Cloud Sleuth可以在整个分布式系统中跟踪一个用户请求的过程,捕获这些跟踪数据,就能构建微服务的整个调用链的视图,是调试和监控微服务的关键工具。

功能:耗时分析;可视化错误;链路优化;

ZipkinTwitter的一个开源项目,致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展示。

使用步骤:(Seuth收集数据,Zipkin展示数据)

1)安装启动zipkinjava -jar zipkin.jar;

2)访问zipkin web界面,http://localhost:9411

3)在各个微服务中分别引入sluethzipkin(其实zipkin包含slueth)依赖;

4)配置;

spring:
  zipkin:
    base-url: http://localhost:9411/
  sleuth:
    sampler:
      probability: 1 #数据采集率 默认0.1 百分之十(采集越多,对性能损耗越大)

 

posted @ 2020-05-23 22:17  wuyiping  阅读(274)  评论(0)    收藏  举报