SpringCloud学习使用(一)——GateWay、SpringCloud Config、SpringCloud Bus、SpringCloud Stream

springcloud的介绍(一)

springboot是一个微服务框架,而springcloud是很多框架的集合它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署

1. springcloud升级过程中弃用和后来新使用的技术(弃用不代表不能用只是不在进行维护)
一张图描述了springcloud的组件升级

在这里插入图片描述

GateWay网关介绍

Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,主要有路由,断言,过滤三大特点,路由主要是根据提供的地址或者微服务名称进行转发,断言相当于在url地址上再加一层防护

GateWay网关使用

使用GateWay要有springboot的环境,下面是需要导入的maven依赖,使用的时候不要导入web模块的start,不然无法启动

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
/*主配置类*/
@SpringBootApplication
@EnableEurekaClient
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication9527.class,args);
    }
}

这里是yml文件的配置

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**  # 断言,路径相匹配的进行路由(这是按着路径进行匹配,在url下找路径符合的)
            #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai](按照时间进行匹配)
            #- Cookie=username,zzyy (按照cookie进行匹配)
            #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式
            断言还有很多可以自己了解一下

创建一个自定义的网关过滤器

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered
{
	/**
     * 
     * @param exchange 相当于request对象
     * @param chain 
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
        log.info("***********come in MyLogGateWayFilter:  "+new Date());

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname == null)
        {
            log.info("*******用户名为null,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
	// 此处代表过滤器的优先级
    @Override
    public int getOrder()
    {
        return 0;
    }
}

SpringCloud Config的介绍

SpringCloud Config 是用来为分布式系统中的微服务应用提供集中化配置的支持。它分为服务端Server和客户端Client,这两部分都是独立的应用,之间通过http进行通信。服务端Server作为配置仓库和客户端的中介,客户端则为分布式系统中的各个微服务应用。

在这里插入图片描述

SpringCloud Config使用

首先使用SpringCloud Config的时候需要在远程仓库创建配置文件,git,github,码云,svn都可,这里介绍了在github上读取配置文件的步骤

需要导入的maven依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
这里是yml文件的配置
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/Adword830/springcloud-config.git #GitHub上面的git仓库名字
          ####搜索目录
          search-paths:
            - springcloud-config
      ####读取分支
      label: master
/*主配置类需要加入的注解*/
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
  public static void main(String[] args) {
    SpringApplication.run(ConfigServer.class, args);
  }
}

在github上需要创建的内容

在这里插入图片描述

使用这个 http://localhost:3344/master/config-dev.yml路径去访问会得到github上面写好的配置文件中的内容如下

cloud:
  config:
    server:
      git:
        uri: https://github.com/Adword830/springcloud-config.git99

以上都是在当前的clinet中直接获取到github上的配置文件,没有通过一个个微服务去通过这个springCloud Config服务去获取配置信息,下面介绍了如何去通过springCloud Config去获取配置信息,这里使用bootstrap.yml配置文件进行配置,application.yml主要是对私使用,bootstrap.yml主要是对公使用优先级大于application.yml

#这里是bootstrap.xml文件中的配置信息
spring:
  cloud:
    #Config客户端配置
    config:
      label: master #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称   上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 #配置中心地址
# 暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

通过http://localhost:3355/configInfo去访问获取到配置信息

@RestController
@RefreshScope/*这个注解代表动态刷新*/
public class ConfigClientController
{
    @Value("${cloud.config.server.git.uri}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo()
    {
        return configInfo;
    }
}

当前获取到的配置信息: https://github.com/Adword830/springcloud-config.git,多个微服务通过这个SpringCloud Config获取到相关的配置信息,这样可以避免有许多个微服务是的时候出现要更改很多配置文件的需求。

SpringCloud Bus消息总线的介绍

SpringCloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和消息中间件的功能,SpringCloud Bus目前支持 RabbitMQ 和 Kafka。SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送,也可以当作微服务间的通信信道

什么是总线?

在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便的广播一些需要让其他连接在该主题上的实例都知道的消息。

在这里插入图片描述

SpringCloud Bus消息总线的使用

使用SpringCloud Config的时候会出现一种问题,当github上的配置文件内容被修改之后,通过SpringCloud Config这个服务获取到的配置信息不会跟着更新,从而导致获取到的配置信息不是实时更新的,这时候就需要发送一个刷新的post请求去刷新这个微服务,这样导致存在多个微服务的时候要多次发送请求刷新,这样导致会很麻烦,SpringCloudBus通过给配置中心这个微服务发送请求让其去提醒从我这里获取配置的微服务我这里的配置更新了,就像是你订阅了微信公众号他更新之后会给你推送一条消息给你我已近更新了,你就明白了现在用的是新的配置文件

在这里插入图片描述

使用SpringCloud Bus消息总线需要导入的maven依赖,这个依赖要导入到消息总线的微服务中还要导入到从其中获取配置的微服务中(这里主要使用的rabbitmq这个消息中间键)

     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

添加了maven依赖的微服务,yml文件也需要添加一下代码

spring:
	rabbitmq:
	    host: localhost
	    port: 5672
	    username: guest
	    password: guest
##rabbitmq相关配置,暴露bus刷新配置的端点
management:
  endpoints: #暴露bus刷新配置的端点
    web:
      exposure:
        include: 'bus-refresh'

通过发送post请求 localhost:3344/actuator/bus-refresh让配置中心微服务发送消息让从这获取配置文件的微服务知道配置已经更新了,如果不想让所有的配置文件全部更新可以通过localhost:3344/actuator/bus-refresh/{微服务名:端口号}来让指定的微服务进行更新

SpringCloud Stream的介绍

springcloud stream是一个构建消息驱动微服务的框架。应用程序通过inputs或者outputs 来与spring cloud stream 中binder对象交互通过我们配置来binding,而spring cloud stream 的binder对象负责与消息中间件交互。所以,我们只需要搞清楚如何与spring cloud stream交互就可以方便使用消息驱动的方式。 通过使用spring intergration 来连接消息代理中间件已实现消息事件驱动。 spring cloud stream 为一些供应商的消息中间件产品提供了个性化的自动化配置,引用发布-订阅,消费组,分区的三个核心概念。spring cloud stream目前仅支持Rabbitmq Kafka

在这里插入图片描述
在这里插入图片描述

SpringCloud Stream的使用

这里是maven依赖,这里主要是使用了RabbitMQ

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

消息生产者的yml文件的配置,主要是使用rabbitmq消息中间键进行消息的生成

spring:
  application:
    name: cloud-stream-provider
  cloud:
    stream:
      binders: # 在此处配置要绑定的rabbitmq的服务信息;
        defaultRabbit: # 表示定义的名称,用于于binding整合
          type: rabbit # 消息组件类型
          environment: # 设置rabbitmq的相关的环境配置
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
      bindings: # 服务的整合处理
        output: # 这个名字是一个通道的名称
          destination: studyExchange # 表示要使用的Exchange名称定义
          content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
          binder: defaultRabbit # 设置要绑定的消息服务的具体设置

定义一个消息生产的接口然后去实现这个接口,重写方法

@EnableBinding(Source.class)/*通过Binding生成一个消息*/
public class MessageProviderImpl implements IMessageProvider {
	@Autowired
    private MessageChannel output;
    
    @Override
    public String send() {
        String serial = UUID.randomUUID().toString();
        output.send(MessageBuilder.withPayload(serial).build());
        System.out.println("****************serial:"+serial);
        return serial;
    }
}

Controller类

@RestController
public class SendMessageController {
	@Autowired
    private final IMessageProvider messageProvider;
    
    @GetMapping("/sendMessage")
    public String sendMessage(){
        return messageProvider.send();
    }
}

通过 http://localhost:8801/sendMessage这个地址去生成消息,后续让消息的消费者去消费这些消息,在RabbitMQ上会出现studyExchange为name的topic,后续订阅了RabbitMQ的消息消费者就可以消费这个topic

在这里插入图片描述

当前yml文件是消息消费者的,其中消费者也是使用的RabbitMQ这一个消息中间键,如果有使用Kafka这一消息中间键的可以吧中间rabbitmq的配置改为Kafka的配置去使用,group这一属性主要是为了让消息不重复使用,例如一个商城发送了一个下订单的消息给订单微服务刚好订单微服务是集群配置的,如果配置了group这一属性就只有其中的一个订单微服务能接受到消息不会导致重复的去扣款,这个属性还有一个特性,当配置了这个属性的消息消费者微服务处于关机状态下,消息生产者生产了新的消息,再去启动这个消息消费者的微服务,他能去把未消费的消息重新去消费。

spring:
  application:
    name: cloud-stream-consumer
  cloud:
    stream:
      binders: # 在此处配置要绑定的rabbitmq的服务信息;
        defaultRabbit: # 表示定义的名称,用于于binding整合
          type: rabbit # 消息组件类型
          environment: # 设置rabbitmq的相关的环境配置
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
      bindings: # 服务的整合处理
        input: # 这个名字是一个通道的名称
          destination: studyExchange # 表示要使用的Exchange名称定义
          content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
          binder: defaultRabbit # 设置要绑定的消息服务的具体设置
          group: consumerA 

Controller类

@RestController
@EnableBinding(Sink.class)
public class ReceiveMessageListenerController {
    @Value("${server.port}")
    private String severPort;

    @StreamListener(Sink.INPUT)
    public void input(Message<String> message){
        System.out.println("消费者1号,----------->接收到的消息:"+message.getPayload()+"\t port"+severPort);
    }
}

版权声明:本文为weixin_43947145原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。