spring cloud 下篇

1. 今日内容
1.Feign
	远程调用
	熔断器支持
	日志配置
2.Gateway--->nginx
    网关搭建
    网关路由
    动态路由
    路由前缀
    过滤器
3.Config配置中心
    搭建配置中心从gitee读取配置文件
    改造用户服务将配置提取至配置中心
4.Bus消息总线
	docker安装rabbitmq
	使用消息总线完成服务配置的的批量更新
一、Feign

介绍:Feign是一个http请求的轻量级别的框架,在cloud中又有“伪装”。

1. 远程调用

步骤:

  • 创建consumer-service-feign模块
    • web/lombok/eureka-client/openfeign
  • 在启动类添加
    • eurekaclient注解
    • 开启feign支持
  • 编写配置文件
    • 复制consumer-service配置文件,建议修服务的应用名称
  • 编写controller、service接口完成调用
  • 测试

过程:

  • 启动类注解

    @SpringBootApplication
    @EnableEurekaClient //注册到注册中心
    @EnableFeignClients //开启feign支持
    public class ConsumerServiceFeignApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(ConsumerServiceFeignApplication.class, args);
    	}
    }
    
    
  • 业务代码

    @RestController
    @RequestMapping("consumer")
    public class ConsumerController {
    
        @Autowired
        private ConsumerService consumerService;
     
        @GetMapping("findUserById/{id}")
        public User findUserById(@PathVariable Integer id){
            return consumerService.findUserById(id);
        }
    }
    
    @FeignClient("user-service")
    public interface ConsumerService {
        /**
         *  String url = "http://user-service/user/findUserById/" + id;
         *  注意事项:
         *      1.feign在使用PathVariable注解时必须显示的声明参数,否则异常
         */
        @GetMapping("user/findUserById/{id}")
        User findUserById(@PathVariable("id") Integer id);
    }
    
  • 在测试的过程中发现feign具备了ribbon的功能

在这里插入图片描述

2. 熔断支持

步骤:

  1. 在配置文件中开启熔断器支持
  2. 编写service的实现类

过程:

  • 配置文件开启支持

    #开启熔断器支持
    feign:
      hystrix:
        enabled: true
    
  • 实现类

    @Component
    public class ConsumerServiceImpl implements ConsumerService {
    
        /*
            服务降级方法
         */
        @Override
        public User findUserById(Integer id) {
            User user = new User();
            user.setId(id);
            user.setNote("服务繁忙,请您稍后再试...");
            return user;
        }
    }
    
  • 在service中声明服务降级的类字节码

    @FeignClient(value = "user-service",fallback = ConsumerServiceImpl.class)
    public interface ConsumerService {
        /**
         *  String url = "http://user-service/user/findUserById/" + id;
         *  注意事项:
         *      1.feign在使用PathVariable注解时必须显示的声明参数,否则异常
         */
        @GetMapping("user/findUserById/{id}")
        User findUserById(@PathVariable("id") Integer id);
    }
    
3. 日志配置

在这里插入图片描述

步骤:

  1. 在配置文件中声明日志级别(info/debug/error)
  2. 编写feign日志配置类
  3. 在service中配置feign日志配置类的class字节码(经测试,可以不配置也会生效)

过程:

  • 配置文件声明日志级别

    #日志级别配置
    logging:
      level:
        com.itheima: debug
    
  • feign配置类

    @Configuration //声明是一个配置类
    public class FeignLogConfig {
    
        /*
            logger注意导包---》 import feign.Logger;
         */
        @Bean
        public Logger.Level configLog(){
            return Logger.Level.FULL;
        }
    }
    
二、Gateway

介绍:网关系统,路由(负载)+鉴权。是用于替换zuul(网关),gateway是cloud自己全新的组件。

在这里插入图片描述

1. 网关搭建

步骤:

  1. 创建gateway-service服务
    • eureka-client
    • gateway
  2. 配置文件
    • 复制配置文件—》修改应用名称
  3. 在启动类添加注解
    • eurekaclient注解

过程:

  • 配置文件

    server:
      port: 10010
    spring:
      application:
        name: gateway-server
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
  • 启动类

    @SpringBootApplication
    @EnableEurekaClient
    public class GatewayServerApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(GatewayServerApplication.class, args);
    	}
    
    }
    
  • 注意事项:

    • 千万不要选择web依赖,gateway启动时使用的是webful。
2. 网关路由
  • 配置文件

    server:
      port: 10010
    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          routes:
            - id: consumer-service-feign-route
              uri: http://localhost:8081
              predicates:
                - Path=/**
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    

    存在问题uri硬编码需要写活------》动态。

3. 动态路由

步骤:

  1. 创建两个消费者的启动类

  2. 修改网关配置文件

    server:
      port: 10010
    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          routes:
            - id: consumer-service-feign-route
            #动态路由通过lb协议可以根据服务的应用名称将服务列表从注册中心获取到本地,然后通过ribbon进行负载
              uri: lb://consumer-service-feign #http://localhost:8081
              predicates:
                - Path=/**
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
4. 路由前缀
  • 添加前缀 + 去除前缀

    server:
      port: 10010
    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          routes:
            - id: consumer-service-feign-route
            #动态路由通过lb协议可以根据服务的应用名称将服务列表从注册中心获取到本地,然后通过ribbon进行负载
              uri: lb://consumer-service-feign #http://localhost:8081
              predicates:
                - Path=/**
              filters:
                #添加前缀
                - PrefixPath=/consumer
                #去除前缀
                - StripPrefix=1
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
    配置请求地址最终地址
    PrefixPath=/consumerhttp://localhost:10010/consumer/findUserById/2http://localhost:8081/consumer/consumer/findUserById/2
    PrefixPath=/consumerhttp://localhost:10010/findUserById/2http://localhost:8081/consumer/findUserById/2
    PrefixPath=/consumer/abchttp://localhost:10010/findUserById/2http://localhost:8081/consumer/abc/findUserById/2
    StripPrefix=1http://localhost:10010/consumer/findUserById/2http://localhost:8081/findUserById/2
    StripPrefix=1http://localhost:10010/consumer/consumer/findUserById/2http://localhost:8081/consumer/findUserById/2
    StripPrefix=2http://localhost:10010/consumer/consumer/findUserById/2http://localhost:8081/findUserById/2
5. 过滤器

在这里插入图片描述

server:
  port: 10010
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: consumer-service-feign-route
        #动态路由通过lb协议可以根据服务的应用名称将服务列表从注册中心获取到本地,然后通过ribbon进行负载
          uri: lb://consumer-service-feign #http://localhost:8081
          predicates:
            - Path=/**
          filters:
            #添加前缀
            - PrefixPath=/consumer
            #去除前缀
            - StripPrefix=1
      #全局过滤器添加响应头
      default-filters:
        - AddResponseHeader=i-love,itheima
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
6. 自定义过滤器

需求:

​ 判断用户是否有登录?通过token令牌? 从请求数据中获取token参数,判断是否为空?

步骤:

  1. 创建类实现全局过滤器,Ordered接口
    • 重写filter方法
      • 获取请求对象
      • 从请求对象中获取请求参数token
      • 对token进行判空校验
      • 如果为空拦截
      • 如果不为空放行
    • order方法
      • 过滤器优先级别—》数值越小优先级别越高
  2. 返回

过程:

  • @Component
    public class MyFilter implements GlobalFilter,Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            //- 获取请求对象
            ServerHttpRequest request = exchange.getRequest();
            //- 从请求对象中获取请求参数token
            String token = request.getQueryParams().getFirst("token");
            //- 对token进行判空校验
            if(StringUtils.isEmpty(token)){ //token为空
                //- 如果为空拦截
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED); //401表示无权限访问
                //编译返回
                return response.setComplete();
            }
            //- 如果不为空放行
            return chain.filter(exchange);
        }
    
        /**
         * @Description: 值越小优先级越高,建议值要小于2,因为路由也是一个过滤器,并且路由过滤器的优先级别为2
        */
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    
  • http://localhost:10010/consumer/findUserById/2?token=121546456485

三、Config配置中心

介绍:

用于管理配置文件,在配置文件中存在两种,一种是叫application.yml一般用于配置一些项目信息,另一种是boostrap.yml一般用于配置项目启动时需要加载的配置,两者bootstrap优先级别更高。

在这里插入图片描述

1. 配置中心服务搭建

步骤:

  1. 创建config-server项目
    • web/eureka-client/config-server
  2. 在启动类添加注解
    • eurekaclient
    • configserver注解声明是一个配置中心
  3. 编写配置文件
    • 端口
    • 应用名称
    • 注册中心
    • git地址(暂时不配置)
  4. 创建git仓库存放配置文件

过程:

  • 启动类添加注解

    @SpringBootApplication
    @EnableEurekaClient //注册到注册中心
    @EnableConfigServer //声明是一个配置中心
    public class ConfigServerApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ConfigServerApplication.class, args);
    	}
    }
    
  • 配置文件

    server:
      port: 1200
    spring:
      application:
        name: config-server
      cloud:
        config:
          server:
            git:
              uri: https://gitee.com/guodongzz/jiuye-31.git
              #账密公开仓库不需要填写,如果是私有仓库必须明文填写,
    #          username:
    #          password:
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
2. 改造用户服务

步骤:

  1. 在gitee创建三个配置文件

    • user-dev.yml

      #db
      spring:
        datasource:
          #serverTimezone=UTC
          url: jdbc:mysql://127.0.0.1/itheima?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: root
          password: root
        application:
          name: user-service
      #mybatis
      mybatis:
        mapper-locations: classpath:mapper/*.xml
        type-aliases-package: com.itheima.pojo
      personName: caixukun-dev
      
    • user-test.yml

      #db
      spring:
        datasource:
          #serverTimezone=UTC
          url: jdbc:mysql://127.0.0.1/itheima?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: root
          password: root
        application:
          name: user-service
      #mybatis
      mybatis:
        mapper-locations: classpath:mapper/*.xml
        type-aliases-package: com.itheima.pojo
      personName: caixukun-test
      
    • user-prod.yml

      #db
      spring:
        datasource:
          #serverTimezone=UTC
          url: jdbc:mysql://127.0.0.1/itheima?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: root
          password: root
        application:
          name: user-service
      #mybatis
      mybatis:
        mapper-locations: classpath:mapper/*.xml
        type-aliases-package: com.itheima.pojo
      personName: caixukun-prod
      
  2. 添加依赖 config

    <dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
  3. 在UserController中获取personName

      	@Value("${personName}")
        private String personName; 
    /**
         * @Author: guodong 
         * @Date: 9:50 2020/9/22
         * @Parms []
         * @ReturnType: java.lang.String
         * @Description: 获取personName区分使用的配置文件环境
        */
        @GetMapping("getPersonName")
        public String getPersonName() {
            return personName;
        }
    
  4. 在配置文件中声明要使用配置中心

    • 将application.yml------>bootstrap.yml

    • 将配置文件中的db+mybatis配置删除

    • 编写配置使用配置中心

      • 声明要使用的配置文件名称
      • 配置文件环境
      • git分支名称
      • 声明要使用配置中心
      • 配置中心的服务id
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:8761/eureka #注册中心的地址
      server:
        port: 9091
      spring:
        cloud:
          config:
          #配置文件名称
            name: user
            profile: dev #配置文件环境
            label: master #git分支名称
            discovery:
              enabled: true #开启使用配置中心
              service-id: config-server #配置中心的服务应用名称
      
3. 配置更新问题

演示:

修改配置文件personName内容刷新91和92服务发现配置信息没有发生变化。

解决:

  1. 导入actuator依赖

    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-actuator</artifactId>
    		</dependency>
    
  2. 暴露刷新地址—》refresh

    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka #注册中心的地址
    server:
      port: 9091
    spring:
      cloud:
        config:
        #配置文件名称
          name: user
          profile: dev #配置文件环境
          label: master #git分支名称
          discovery:
            enabled: true #开启使用配置中心
            service-id: config-server #配置中心的服务应用名称
    management:
      endpoints:
        web:
          exposure:
            include: refresh  #暴露刷新地址
    
  3. 在UserController添加@RefreshScope注解表示允许刷新

    @RefreshScope //表示允许刷新
    public class UserController {
        
        //省略
    }
    
  4. 使用postman请求刷新地址发送post请求

    http://localhost:9091/actuator/refresh

    http://localhost:9092/actuator/refresh

注意:

  • 刷新时必须使用post请求
  • 暴露的刷新地址必须叫refresh
四、Bus-消息总线

介绍:

​ 消息总线,类比于微信,用于发送接收消息。

1. 安装RabbitMq
#docker复习
docker images
docker search 镜像名称
docker pull 镜像名称:版本号
docker rmi 镜像名称:版本号
docker images -q

docker ps 
docker ps -a
#交互式容器 一旦创建直接进入容器内部,退出容器后容器自动停止运行
docker run -it --name=容器名称 镜像 /bin/bash 
#守护式容器  创建后不会进入容器内部,需要使用命令方可进入,容器退出后不会停止运行
docker run -id --name=容器名称 -p 外部端口:内部端口 镜像

docker start 容器名称
docker stop 容器名称
docker rm 容器名称 #运行时的容器需要停止后再删除
docker rm -f  容器名称 #不建议使用

#安装mq
docker run -id --name=c_rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:management
#测试访问
http://ip:15672 #如果可以看到管理页面代表部署成功 账密: guest/guest
2. 改造配置中心

步骤:

  1. 导入bus-amqp依赖、actuator依赖

    	<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-bus-amqp</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-actuator</artifactId>
    		</dependency>
    
  2. 修改配置文件

    • mq配置信息

    • 暴露刷新地址

    • server:
        port: 1200
      spring:
        application:
          name: config-server
        cloud:
          config:
            server:
              git:
                uri: https://gitee.com/guodongzz/jiuye-31.git
        rabbitmq:
          host: 192.168.200.132
          #以下三个配置使用默认值即可
      #    port: 5672
      #    username: guest
      #    password: guest
                #账密公开仓库不需要填写,如果是私有仓库必须明文填写,
      #          username:
      #          password:
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:8761/eureka
            #暴露刷新地址
      management:
        endpoints:
          web:
            exposure:
              include: bus-refresh
      
      
3. 改造用户服务

步骤:

  1. 导入bus-amqp依赖
  2. 在配置文件中添加mq信息
  3. 在UserController添加@RefreshScope注解表示允许刷新(已经添加过,此处无需再次添加)
4. 使用postman批量刷新,post请求

http://localhost:1200/actuator/bus-refresh

5 扩展:刷新单个服务

http://localhost:1200/actuator/bus-refresh/user-service:9091

6. bus刷新流程

在这里插入图片描述

  1. 使用postman请求config-server配置中心
  2. 配置中心发送更新消息到mq
  3. 用户服务监听到消息
  4. 用户服务从配置中心主动拉取配置文件
  5. 配置中心从gitee获取最新的配置文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃 哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值