SpringBoot和SpringCloud配置

一、springBoot配置

1.1、yml

端口

server:
  port: 8089

应用名称

spring:
  application:
    name: eureka-server

项目访问路径

server:
  servlet:
    context-path: /java521

数据库

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
	#url: jdbc:mysql://localhost:3306/user?characterEncoding=utf8&autoReconnect=true&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root

mybatis

mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml	#xml路径
  type-aliases-package: com.java521.pojo	#扫描包

redis

spring:
  redis:
    host: localhost
    port: 6379
    password: 
    database: 0

1.2、pom

打包插件

<build>
     <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
      </plugins>
  </build>

1.3、RestTemplate

在Application启动类中添加

@Bean
public RestTemplate restTemplate(){
     return new RestTemplate(); 
}

然后使用的时候

@Autowired
private RestTemplate restTemplate;

二、注册中心 Spring Cloud Eureka

官方推荐端口 8761

2.1、yml配置

应用名称

spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中作为服务的id标识(serviceId)

eureka配置

eureka:
  client:
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要写其它Server的地址。
      defaultZone: http://127.0.0.1:8761/eureka

关闭自己注册自己 不设置会报错 但不影响使用 如果是集群 需要开启

eureka:
    client:
        fetch-registry: false  #是否抓取注册列表
        register-with-eureka: false  #是否注册服务中心Eureka

在生产者和消费者pom文件中添加eureka中的

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-dependencies</artifactId>
           <version>${spring-cloud.version}</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>

并且要添加版本到properties中

<spring-cloud.version>Greenwich.SR3</spring-cloud.version>

除此之外,生产者和消费者还需要添加eureka客户端到dependencies中

 <!--eureka客户端starter-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

生产者和消费者修改配置文件:spring.application.name指定应用名称,作为服务ID使用,并配置eureka注册中心地址

spring:
    application:
        name: provider-service
#配置eurekaserver
eureka:
    client:
        service-url:
            defaultZone: http://127.0.0.1:8761/eureka

Eureka Application启动类

添加@EnableEurekaServer
声明是一个eureka服务端

将服务注册到注册中心, 在生产者和消费者application中添加注解,二选一

@EnableEurekaClient		//将服务注册到eureka
@EnableDiscoveryClient	//将服务注册到注册中心

消费者使用
添加依赖注入

@Autowired
private DiscoveryClient discoveryClient;

消费者通过注册中心调用生产者

//获取服务列表
List<ServiceInstance> list = discoveryClient.getInstances("provider-service");
//获取uri
URI uri = list.get(0).getUri();
//url连接
String url = uri + "/user/findUserById/" + id;	//请求服务者地址
User user = restTemplate.getForObject(url, User.class);	//类的class
return user;

2.2、注意

如果打开eureka使用的是主机名
在这里插入图片描述
想用ip进行注册添加如下配置, 在生产者中和消费者中添加

eureka:
    instance:
        prefer-ip-address: true
        instance-id: ${spring.cloud.client.ip-address}:${server.port} #管控台展示服务ip+port

2.3、基础架构

在这里插入图片描述
Eureka架构中的三个核心角色

  • 服务注册中心:Eureka服务端应用,提供服务注册发现功能,eureka-server
  • 服务提供者:提供服务的应用
    • 要求统一对外提供Rest风格服务即可
    • 本例子:provider-service
  • 服务消费者:从注册中心获取服务列表,知道去哪调用服务方,consumer-service

2.4、Eureka客户端

服务提供者要向EurekaServer注册服务,并完成服务续约等工作

服务注册过程:

  1. 当我们导入了eureka-client依赖坐标,配置Eureka服务注册中心地址
  2. 服务在启动时,会检测是否有@DiscoveryClient注解和配置信息
  3. 如果有,则会向注册中心发起注册请求,携带服务元数据信息
  4. Eureka注册中心会把服务的信息保存在Map中。
    服务续约过程:
    服务每隔30秒会向注册中心续约(心跳)一次,如果没有续约,租约在90秒后到期,然后服务会被失效。每隔30秒的续约操作我们称之为:心跳检测。
#向Eureka服务中心集群注册服务
eureka:
  instance:
   # 租约续约间隔时间,默认30秒
    lease-renewal-interval-in-seconds: 30 
  	# 租约到期,服务时效时间,默认值90秒
    lease-expiration-duration-in-seconds: 90 
  • 两个参数可以修改服务续约行为
    • lease-renewal-interval-seconds:90,租约到期时效时间,默认90秒
    • lease-expiration-duration-in-seconds:30,租约续约间隔时间,默认30秒
  • 服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除

获取服务列表:
每隔30秒服务会从注册中心中拉取一份服务列表
这个时间可以通过配置修改

#向Eureka服务中心集群注册服务
eureka:
  client:
  	# 每隔多久获取服务中心列表,(只读备份)
    registry-fetch-interval-seconds: 30 
  • 服务消费者启动时,会检测是否获取服务注册信息配置
  • 如果是,则会从 EurekaServer服务列表获取只读备份,缓存到本地
  • 每隔30秒,会重新获取并更新数据
  • 每隔30秒的时间可以通过配置registry-fetch-interval-seconds修改

2.5、Eureka服务端

服务下线:

  • 当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer。
  • 服务中心接受到请求后,将该服务置为下线状态

失效剔除:
Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认值为60)进行检查,如果发现实例在在一定时间(此值由客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到心跳,则会注销此实例。

自我保护:
Eureka会统计服务实例最近15分钟心跳续约的比例是否低于85%,如果低于则会触发自我保护机制。
服务中心页面会显示如下提示信息
在这里插入图片描述
含义:紧急情况!Eureka可能错误地声称实例已经启动,而事实并非如此。续约低于阈值,因此实例不会为了安全而过期。

  • 自我保护模式下,不会剔除任何服务实例
  • 自我保护模式保证了大多数服务依然可用
  • 通过enable-self-preservation配置可用关停自我保护,默认值是打开
  #向Eureka服务中心集群注册服务
  eureka:
    server:
      enable-self-preservation: false # 关闭自我保护模式(缺省为打开)

三、负载均衡 Spring Cloud Ribbon [ˈrɪbən]

3.1、实现负载均衡访问用户服务。

如果想要做负载均衡,我们的服务至少2个以上,所以我们先来在idea中启动两个生产者。

实现步骤:
第一步:启动多个provider-service服务
第二步:开启消费者负载均衡

1、在RestTemplate的注入方法上加入@LoadBalanced注解

@Bean
@LoadBalanced//开启负载均衡
public RestTemplate restTemplate(){
    return new RestTemplate();
}

2、修改调用请求的Url地址,改为服务名称调用

String url = "http://provider-service/user/findUserById/" + id;	//通过服务名称调用

3.2、负载策略

Ribbon内置了多种负载均衡策略,内部负责复杂均衡的顶级接口为:com.netflix.loadbalancer.IRule ,实现方式如下 :
在这里插入图片描述

  • com.netflix.loadbalancer.RandomRule :随机选择一个server
  • com.netflix.loadbalancer.RetryRule :对选定的负载均衡策略机上重试机制。
  • com.netflix.loadbalancer.RoundRobinRule :以轮询的方式进行负载均衡
  • com.netflix.loadbalancer.WeightedResponseTimeRule :根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。
  • com.netflix.loadbalancer.AvailabilityFilteringRule :可用过滤策略,过滤掉故障和请
    求数超过阈值的服务实例,再从剩下的实例中轮询调用(默认)

服务消费者的application.yml配置文件中修改负载均衡策略,格式:
{服务提供者名称}.ribbon.NFLoadBalancerRuleClassName

# 修改服务地址轮询策略,默认是轮询,配置之后变随机,RandomRule
provider-service:
	ribbon:
  		NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3.3、Ribbon关键组件

在这里插入图片描述

  • ServerList:可以响应客户端的特定服务的服务器列表。
  • ServerListFilter:可以动态获得的具有所需特征的候选服务器列表的过滤器。
  • ServerListUpdater:用于执行动态服务器列表更新。
  • Rule:负载均衡策略,用于确定从服务器列表返回哪个服务器。
  • Ping:客户端用于快速检查服务器当时是否处于活动状态。
  • LoadBalancer:负载均衡器,负责负载均衡调度的管理。

四、熔断器 Spring Cloud Hystrix

4.1、Hystrix 简介

Hystrix,英文意思是豪猪,全身是刺,刺是一种保护机制。Hystrix也是Netflix公司的一款组件。
Hystrix的作用是什么?
Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库、防止出现级联失败也就是雪崩效应

4.2、雪崩效应

  • 微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
  • 如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
  • 单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应;
    在这里插入图片描述
    Hystrix解决雪崩问题的手段,主要是服务降级**(兜底)**,线程隔离;

4.3、熔断案例

目标:服务提供者的服务出现了故障,服务消费者快速失败给用户友好提示。体验服务降级

实现步骤:
1、引入熔断的starter依赖坐标
2、消费者服务开启熔断的注解
3、编写服务降级处理的方法
4、配置熔断的策略
5、模拟异常代码
6、测试熔断服务效果
实现过程:
1、引入熔断的依赖坐标:
consumer-service中加入依赖

<!--熔断Hystrix starter-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2、开启熔断的注解
@SpringCloudApplication =等同于@SpringBootApplication+@EnableDiscoveryClient+@EnableCircuitBreaker

//注解简化写法:微服务中,注解往往引入多个,简化注解可以使用组合注解。@SpringCloudApplication =等同于@SpringBootApplication+@EnableDiscoveryClient+@EnableCircuitBreaker
/*
@SpringBootApplication
@EnableDiscoveryClient//开启服务发现
@EnableCircuitBreaker//开启熔断
*/
@SpringCloudApplication
public class ConsumerApplication {
    @Bean
    @LoadBalanced//开启负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
}

3、编写服务降级处理方法:使用@HystrixCommand定义fallback方法。
注意:熔断服务降级方法必须保证与被降级方法相同的参数列表和返回值。

@GetMapping("/findUserById/{id}")
@HystrixCommand(fallbackMethod ="fallBackMethod")
public User findUserById(@PathVariable Integer id){
    String url = "http://provider-service/user/findUserById/" + id;
    return restTemplate.getForObject(url,User.class);
}

//熔断方法
//要求: 1、返回数据类型必须与原方法一致
//      2、入参必须与原方法一致
public User fallBackMethod(Integer id){
    User user = new User();
    user.setId(id);
    user.setName("熔断方法");
    return user;
}

4、配置熔断策略

  • 常见熔断策略配置
  • 熔断后休眠时间:sleepWindowInMilliseconds
  • 熔断触发最小请求次数:requestVolumeThreshold
  • 熔断触发错误比例阈值:errorThresholdPercentage
  • 熔断超时时间:timeoutInMilliseconds
# 配置熔断策略:
hystrix:
  command:
    default:
      circuitBreaker:
        forceOpen: false # 强制打开熔断器 默认false关闭的
        errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
        sleepWindowInMilliseconds: 5000  # 熔断后休眠时长,默认值5秒
        requestVolumeThreshold: 20  # 熔断触发最小请求次数,默认值是20
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000  # 熔断超时设置,默认为1秒

5、停止生产者服务,模拟服务异常,然后访问消费者会发现走了熔断方法。
6、测试访问超时:服务提供者线程休眠超过5秒,访问消费者触发fallback方法。

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    /**
     * @Author: guodong
     * @Date: 15:04 2019/10/8
     * @Description: 根据id查找用户
     */
    @Override
    public User findUserById(Integer id) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return userMapper.findUserById(id);
    }
}

7、测试
在这里插入图片描述

4.4、总结

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

五、远程调用 Spring Cloud Feign

Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,是以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。

Feign将请求的发送伪装到接口中

**封装了Http调用流程,更符合面向接口化的编程习惯。**类似Dubbo服务调用。

5.1、入门案例

1、导入依赖
在consumer-service中添加spring-cloud-starter-openfeign依赖

<!--配置feign-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、Feign的客户端
在consumer-service中编写Feign客户端接口类ConsumerService

@FeignClient(value = "provider-service")
public interface ConsumerService {
    @RequestMapping("/user/findUserById/{id}")
    User findUserById(@PathVariable("id") Integer id);
}
  • Feign会通过动态代理,帮我们生成实现类。
  • 注解@FeignClient声明Feign的客户端,指明服务名称
  • 接口定义的方法,采用SpringMVC的注解。Feign会根据注解帮我们生成URL地址
    3、编写ConsumerFeignController,使用ConsumerService访问
    @Autowired注入ConsumerService
@FeignClient(value = "provider-service")
public interface UserService {
    @GetMapping("/user/findUserById/{id}")
    User findUserById(@PathVariable("id") Integer id);
}

4、开启Feign功能
在ConsumerApplication启动类上,添加@EnableFeignClients注解,开启Feign功能

@SpringCloudApplication
@EnableFeignClients //开启Feign自动配置支持
public class ConsumerServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerServerApplication.class, args);
    }
}

5、启动测试:访问接口
http://localhost:8081/user/findUserById/2,正常获取结果
在这里插入图片描述

5.2、注意

/1 Resuful方式使用@PathVariable
?id=1 问号传参方式使用@RequestParam

5.3、熔断器支持

Feign本身也集成Hystrix熔断器,starter内查看。
在这里插入图片描述
服务降级方法实现步骤:
1、在配置文件application.yml中开启feign熔断器支持
2、编写FallBack处理类,实现FeignClient客户端
3、在@FeignClient注解中,指定FallBack处理类。
4、测试服务降级效果

实现过程:
1、在配置文件application.yml中开启feign熔断器支持:默认关闭

feign:
	hystrix:
		enabled: true # 开启Feign的熔断功能

2、 定义一个类ConsumerServiceImpl,实现刚才编写的ConsumerService,作为FallBack的处理类

@Component
public class ConsumerServiceImpl implements ConsumerService {
    //熔断方法
    @Override
    public User findUserById(Integer id) {
        User user = new User();
        user.setId(id);
        user.setNote("网络异常,请稍后再试...");
        return user;
    }
}

3、在@FeignClient注解中,指定FallBack处理类。。

@FeignClient(value = "provider-service",fallback = ConsumerServiceImpl.class)
public interface ConsumerService {
   // String url = "http://provider-service/user/findUserById/" + id;
   @RequestMapping("/user/findUserById/{id}")
   User findUserById(@PathVariable("id") Integer id);
}

4、重启测试:关闭provider-service服务,然后在页面访问;http://localhost:8081/consumer/findUserById/1

5.4、请求压缩和响应压缩

SpringCloudFeign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。
通过配置开启请求与响应的压缩功能:

feign:
	compression:
        request:
            enabled: true # 开启请求压缩
        response:
            enabled: true # 开启响应压缩

也可以对请求的数据类型,以及触发压缩的大小下限进行设置

#  Feign配置
feign:
	compression:
		request:
			enabled: true # 开启请求压缩
			mime-types:	text/html,application/xml,application/json # 设置压缩的数据类型
			min-request-size: 2048 # 设置触发压缩的大小下限
			#以上数据类型,压缩大小下限均为默认值

5.5、配置日志级别

在发送和接收请求的时候,Feign定义了日志的输出定义了四个等级:这里我们配置测试一下。

级别说明
NONE不做任何记录
BASIC只记录输出Http 方法名称、请求URL、返回状态码和执行时间
HEADERS记录输出Http 方法名称、请求URL、返回状态码和执行时间 和 Header 信息
FULL记录Request 和Response的Header,Body和一些请求元数据

实现步骤:

  1. 在application.yml配置文件中开启日志级别配置
  2. 编写配置类,定义日志级别bean。
  3. 在接口的@FeignClient中指定配置类
  4. 重启项目,测试访问

实现过程:

1、在consumer-service的配置文件中设置com.itheima包下的日志级别都为debug

# com.itheima 包下的日志级别都为Debug
logging:
  level:
    com.itheima: debug

2、在consumer-service编写配置类,定义日志级别

@Configuration
public class FeignLogLevleConfig {
    //采用full打印日志
    @Bean
    public Logger.Level configLog(){
        return Logger.Level.FULL;
    }
}

3、在consumer-service的ConsumerService中指定配置类

@FeignClient(value = "provider-service",
        fallback = ConsumerServiceImpl.class,
        configuration = FeignLogLevleConfig.class)
public interface ConsumerService {

    @RequestMapping("/user/findUserById/{id}")
    User findUserById(@PathVariable("id") Integer id);
}

4、重启项目,即可看到每次访问的日志
在这里插入图片描述

六、网关 Spring Cloud Gateway

6.1、简介

Spring Cloud Gateway 是Spring Cloud团队的一个全新项目,基于Spring 5.0、SpringBoot2.0、Project Reactor 等技术开发的网关。旨在为微服务架构提供一种简单有效统一的REST 请求路由管理方式

Spring Cloud Gateway 作为SpringCloud生态系统中的网关,目标是替代Netflix Zuul。Gateway不仅提供统一路由方式,并且基于Filter链的方式提供网关的基本功能。例如:安全,监控/指标,和限流。

本身也是一个微服务,需要注册到Eureka
**网关的核心功能:**过滤(权限)、路由

核心概念:

  • 路由(route):
  • **断言Predicate函数:**路由转发规则
  • 过滤器(Filter):
    在这里插入图片描述
  • 不管是来自客户端的请求,还是服务内部调用。一切对服务的请求都可经过网关。
  • 网关实现鉴权、动态路由等等操作。
  • Gateway是我们服务的统一入口

6.2、快速入门

搭建网关微服务,实现服务路由分发。

实现步骤:

  1. 创建SpringBoot工程gateway-server
  2. 勾选starter:网关、Eureka客户端
  3. 编写基础配置
  4. 编写路由规则
  5. 启动网关服务进行测试

实现过程:

1、创建SpringBoot工程gateway-server[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hzs6QCZd-1615724762033)(springcloud-02/1571299918242.png)]

2、勾选Starter:网关、Eureka客户端[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EKIOQyXy-1615724762034)(springcloud-02/1564920887287.png)]

3、启动引导类开启注册中心Eureka客户端发现

@SpringBootApplication
@EnableDiscoveryClient// 开启Eureka客户端发现功能
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class,args);
    }
}

4、编写基础配置

  • 在gateway_server中创建application.yml文件,配置
     server:
       port: 10010
     spring:
       application:
         name: gateway-service # 应用名
     # Eureka服务中心配置
     eureka:
       client:
         service-url:
           # 注册中心Eureka服务地址
           defaultZone: http://127.0.0.1:8761/eureka

5、编写路由规则

  • 需要用网关来路由provider-service服务,查看服务ip和端口[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6hbctgup-1615724762036)(springcloud-02/1571299740919.png)]
  • 修改gateway-server的配置文件application.yml,配置网关内容
spring:
    cloud:
      gateway:
        # 路由si(集合)
        routes:
            # id唯一标识
          - id: consumer-service-route
            # 路由服务地址
            uri: http://127.0.0.1:8081
            # 断言
            predicates:
              - Path=/**
  • 将符合path规则的请求,路由到uri参数指定地址。
  • 举例:http://localhost:10010/user/findUserById/1 路由转发到http://localhost:8081/user/findUserById/1

6、启动GatewayApplication进行测试

6.3、动态路由

刚才路由规则中,我们把路径对应服务地址写死了!如果服务提供者集群的话,这样做不合理。应该是根据服务名称,去Eureka注册中心查找服务对应的所有实例列表,然后进行动态路由!

  • 修改映射配置:通过服务名称获取
  • 因为已经配置了Eureka客户端,可以从Eureka获取服务的地址信息,修改application.yml文件如下
 # 注解版
server:
  port: 10010
spring:
  application:
    name: gateway-service # 应用名
    # Eureka服务中心配置
  cloud:
    gateway:
      # 路由si(集合)
      routes:
        # id唯一标识
        - id: consumer-service-route
          # 路由服务地址
          #uri: http://127.0.0.1:8081
          uri: lb://provider-service
          # 断言
          predicates:
            - Path=/user/**
eureka:
  client:
    service-url:
      # 注册中心Eureka服务地址
      defaultZone: http://127.0.0.1:8761/eureka
  • 路由配置中uri所用的协议为lb时,gateway将把consumer-service解析为实际的主机和端口,并通过Ribbon进行负载均衡。
  • 启动GatewayApplication测试

6.4、路由前缀

第一:添加前缀:
在gateway中可以通过配置路由的过滤器PrefixPath 实现映射路径中的前缀添加。可以起到隐藏接口地址的作用,避免接口地址暴露。
1、配置请求地址添加路径前缀过滤器

   spring:
     cloud:
       gateway:
         routes:
           - id: consumer-service-route # 路由id,可以随意写
             # 代理服务地址;lb表示从Eureka中获取具体服务
             uri: lb://consumer-service
             # 路由断言,配置映射路径
             predicates:
               - Path=/**
             # 请求地址添加路径前缀过滤器
             filters:
               - PrefixPath=/consumer

2、重启GatewayApplication
3、配置完成的效果:

配置访问地址路由地址
PrefixPath=/consumerlocalhost:10010/findUserById/1localhost:8081/consumer/findUserById/1
PrefixPath=/consumer/abclocalhost:10010/findUserById/1localhost:8081/consumer/abc/findUserById/1

第二:去除前缀:
在gateway中通过配置路由过滤器StripPrefix,实现映射路径中地址的去除。通过StripPrefix=1来指定路由要去掉的前缀个数。如:路径/api/consumer/findUserById/1将会被路由到/consumer/findUserById/1

1、配置去除路径前缀过滤器

server:
  port: 10010
spring:
  application:
    name: gateway-service # 应用名
    # Eureka服务中心配置
  cloud:
    gateway:
      # 路由si(集合)
      routes:
        # id唯一标识
        - id: consumer-service-route
          # 路由服务地址
          #uri: http://127.0.0.1:8081
          uri: lb://provider-service
          # 断言
          predicates:
            - Path=/** # 请求地址添加路径前缀过滤器
          filters:
            #- PrefixPath=/user #添加前缀
            - StripPrefix=1 #去除前缀
eureka:
  client:
    service-url:
      # 注册中心Eureka服务地址
      defaultZone: http://127.0.0.1:8761/eureka

2、重启GatewayApplication
3、访问查看效果

配置访问地址路由地址
StripPrefix=1localhost:10010/api/consumer/findUserById/1localhost:8081/consumer/findUserById/1
StripPrefix=2localhost:10010/aa/api/consumer/findUserById/1localhost:8081/consumer/findUserById/1

6.5、过滤器

6.5.1、简介

过滤器作为网关的其中一个重要功能,就是实现请求的鉴权。前面的路由前缀章节中的功能也是使用过滤器实现的。
Gateway自带过滤器有几十个,常见自带过滤器有:

过滤器名称说明
StripPrefix对匹配上的请求路径去除前缀
PrefixPath对匹配上的请求路径添加前缀
AddRequestHeader对匹配上的请求加上Header
AddRequestParameter对匹配上的请求添加参数
AddResponseHeader对从网关返回的响应添加Header

详细说明官方链接
使用场景:

  • 请求鉴权:如果没有访问权限,直接进行拦截
  • 异常处理:记录异常日志
  • 服务调用时长统计

6.5.2、过滤器配置

**过滤器类型:**Gateway有两种过滤器

  • 局部过滤器:只作用在当前配置的路由上。
  • 全局过滤器:作用在所有路由上。
    配置全局过滤器:
    对输出的响应设置其头部属性名称为i-love,值为itheima
    1、修改配置文件
server:
  port: 10010
spring:
  application:
    name: gateway-service # 应用名
  cloud:
    gateway:
      default-filters:
        - AddResponseHeader=i-love,java
      # 路由si(集合)
      routes:
        # id唯一标识
        - id: consumer-service-route
          # 路由服务地址
          #uri: http://127.0.0.1:8081
          uri: lb://provider-service
          # 断言
          predicates:
            - Path=/** # 请求地址添加路径前缀过滤器
          filters:
            #- PrefixPath=/user #添加前缀
            - StripPrefix=1 #去除前缀
# Eureka服务中心配置
eureka:
  client:
    service-url:
      # 注册中心Eureka服务地址
      defaultZone: http://127.0.0.1:8761/eureka

2、查看浏览器响应头信息
在这里插入图片描述

6.5.3、执行顺序

Spring Cloud Gateway 的 Filter 的执行顺序有两个:“pre” 和 “post”。“pre”和 “post” 分别会在请求被执行前调用和被执行后调用。 在这里插入图片描述
这里的 prepost可以通过过滤器的 GatewayFilterChain 执行filter方法前后来实现。

6.6、自定义全局过滤器

需求:模拟一个登录的校验。基本逻辑:如果请求中有token参数,则认为请求有效,放行;如果没有拦截返回http 401。
实现步骤:
1、在gateway-server工程编写全局过滤器类MyGlobalFilter
2、编写业务逻辑代码:判断如果包含token值,则放行请求,如果不包含则拦截
3.、访问接口测试,加token和不加token。
实现过程:

  1. 在gateway_server工程编写全局过滤器类MyGlobalFilter
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("-----------------全局过滤器MyGlobalFilter---------------------");
        //1、获取参数中的token,以及token的值
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        //2、如果token的值为空,则拦截
        if (StringUtils.isEmpty(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 定义过滤器执行顺序
     * 返回值越小,越靠前执行
     * @return
     */
    @Override
    public int getOrder() {
        return 0;//
    }
}

2、访问:http://localhost:10010/aaa/user/findUserById/1
在这里插入图片描述
3.、访问:http://localhost:10010/aaa/user/findUserById/1?token=1
在这里插入图片描述

七、配置中心 Spring Cloud Config

7.1、Config简介

分布式系统中,由于服务数量非常多,配置文件分散在不同微服务项目中,管理极其不方便。为了方便配置文件集中管理,需要分布式配置中心组件。在Spring Cloud中,提供了Spring Cloud Config,它支持配置文件放在配置服务的本地,也支持配置文件放在远程仓库Git(GitHub、码云)。配置中心本质上是一个微服务,同样需要注册到Eureka服务中心!

配置中心,也是一个微服务,注册到注册中心

在这里插入图片描述
【配置中心的架构图】

7.2、配置中心整合步骤:

  • 配置文件集中放在码云
  • 配置中心获取码云配置文件
  • 用户服务获取配置中心文件

7.3、搭建配置中心微服务

实现步骤:
1、创建配置中心SpringBoot项目config-server
2、勾选Starter坐标依赖:配置中心starter,Eureka客户端starter
3、启动类添加开启配置中心服务注解
4、配置服务中心application.yml文件
5、启动测试
实现过程:
1、启动类:创建配置中心工程config_server的启动类ConfigServerApplication

@SpringBootApplication
@EnableDiscoveryClient//开启Eureka客户端发现功能
@EnableConfigServer //开启配置服务支持
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class,args);
    }
}

2、 配置文件:创建配置中心工程config_server的配置文件application.yml

# 应用基本信息
server:
  port: 1200 # 端口号
spring:
  application:
    name: config-server # 应用名
  cloud:
    config:
      server:
        git:
          # 配置gitee的仓库地址
          uri: https://gitee.com/guodongzz/itheima-361.git
# Eureka服务中心配置
eureka:
  client:
    service-url:
      # 注册Eureka Server

注意:上述spring.cloud.config.server.git.uri是在码云创建的仓库地址,如果仓库创建时设置为私有的,需要在配置文件中增加用户名、密码配置信息。
3、启动测试:启动eureka注册中心和配置中心;

  • 访问http://localhost:1200/user-dev.yml查看能否输出码云存储管理的user-dev.yml文件
  • 并且可以在gitee上修改user-dev.yml,然后刷新上述测试地址也能及时更新数据

7.4、服务去获取配置中心配置

关于application.yml和bootstrap.yml文件的说明:

  • bootstrap.yml文件是SpringBoot的默认配置文件,而且其加载时间相比于application.yml更早。
  • bootstrap.yml和application.yml都是默认配置文件,但定位不同
    • bootstrap.yml相当于项目启动的引导文件
    • application.yml文件是微服务的常规配置参数,变化比较频繁
  • 搭配spring-cloud-config使application.yml的配置可以动态替换。

目标:改造provider-service工程,配置文件不再由微服务项目提供,而是从配置中心获取。
实现步骤:
1、在provider-service中添加starter-config依赖
2、修改服务提供者的配置文件
3、启动服务,测试效果

实现过程:
1、添加依赖(注意这里的依赖与配置中心服务的依赖有区别)

<!--spring cloud 配置中心-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

2、修改配置

  • 创建provider-service工程bootstrap.yml配置文件,配置内容如下
server:
   port: 9091
 # 基本应用信息     
 spring:
   cloud:
     config:
       name: user # 与远程仓库中的配置文件的application保持一致,{application}-{profile}.yml
       profile: dev # 远程仓库中的配置文件的profile保持一致
       label: master # 远程仓库中的版本保持一致
       discovery:
         enabled: true # 使用配置中心
         service-id: config-server # 配置中心服务id

3、启动测试:

  • 依次启动:注册中心、配置中心、用户中心provider-service
  • 如果启动没报错,其实已经使用上配置中心内容了

7.5、配置中心存在的问题

复现问题步骤:
1、修改远程Git配置

  • 修改在码云上的user-dev.yml文件,添加一个属性personName
    2、修改UserController
@RestController
@RequestMapping("/user")
public class UserController {

    @Value("${server.port}")
    private String port;

    @Value("${personName}")
    private String perName;

    @Autowired
    UserService userService;

    //根据id查询
  	@GetMapping("/findUserById/{id}")
    public User findUserById(@PathVariable Integer id){
        /*try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        User user = userService.findUserById(id);
        user.setNote("生产者端口号: " + port);
        return user;
    }
    
    /**
     * 获取配置文件中的personName
    **/
    @RequestMapping("/getPerName")
    public String getPerName(){
        return perName;
    }
}

3、测试:

  • 依次启动Eureka,配置中心,用户微服务;
  • 不要开启消费者服务,因为消费者服务是8081,端口冲突
  • 然后我们修改的user-dev.yml中personName=zhangsan-test01 ,访问用户微服务,查看输出内容并没有发生变化。
    结论:通过浏览器输出结果发现,我们对于Git仓库中的配置文件的修改,并没有及时更新到provider-service微服务,只有重启用户微服务才能生效。

7.6、服务手动刷新更新配置

步骤:
1、添加依赖
2、修改配置文件暴露
3、Controller添加 @RefreshScope注解
4、启动测试,修改git仓库中配置文件,并发送post请求 http://localhost:9091/actuator/refresh
过程:
1、添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2、修改配置文件

#暴露刷新地址
management:
  endpoints:
    web:
      exposure:
        include: refresh

3、Controller添加 @RefreshScope注解
4、启动测试,修改git仓库中配置文件,并发送post请求 http://localhost:9091/actuator/refresh
问题:服务器少的情况系可以分别手动刷新,如果有100台服务器呢?
SpringCloud Bus,解决上述问题,实现配置自动更新。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值