SpringBoot和SpringCloud配置

  • 一、springBoot配置
    • 1.1、yml
    • 1.2、pom
    • 1.3、RestTemplate
  • 二、注册中心 Spring Cloud Eureka
    • 2.1、yml配置
    • 2.2、注意
    • 2.3、基础架构
    • 2.4、Eureka客户端
    • 2.5、Eureka服务端
  • 三、负载均衡 Spring Cloud Ribbon [ˈrɪbən]
    • 3.1、实现负载均衡访问用户服务。
    • 3.2、负载策略
    • 3.3、Ribbon关键组件
  • 四、熔断器 Spring Cloud Hystrix
    • 4.1、Hystrix 简介
    • 4.2、雪崩效应
    • 4.3、熔断案例
    • 4.4、总结
  • 五、远程调用 Spring Cloud Feign
    • 5.1、入门案例
    • 5.2、注意
    • 5.3、熔断器支持
    • 5.4、请求压缩和响应压缩
    • 5.5、配置日志级别
  • 六、网关 Spring Cloud Gateway
    • 6.1、简介
    • 6.2、快速入门
    • 6.3、动态路由
    • 6.4、路由前缀
    • 6.5、过滤器
      • 6.5.1、简介
      • 6.5.2、过滤器配置
      • 6.5.3、执行顺序
    • 6.6、自定义全局过滤器
  • 七、配置中心 Spring Cloud Config
    • 7.1、Config简介
    • 7.2、配置中心整合步骤:
    • 7.3、搭建配置中心微服务
    • 7.4、服务去获取配置中心配置
    • 7.5、配置中心存在的问题
    • 7.6、服务手动刷新更新配置

一、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=falsedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: root

mybatis

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

redis

spring:redis:host: localhostport: 6379password: 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: trueinstance-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  # 熔断触发最小请求次数,默认值是20execution:isolation:thread:timeoutInMilliseconds: 1000  # 熔断超时设置,默认为1秒

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

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;/*** @Author: guodong* @Date: 15:04 2019/10/8* @Description: 根据id查找用户*/@Overridepublic 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 {//熔断方法@Overridepublic 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打印日志@Beanpublic 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: 10010spring: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:8081uri: 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=/consumer localhost:10010/findUserById/1 localhost:8081/consumer/findUserById/1
PrefixPath=/consumer/abc localhost:10010/findUserById/1 localhost: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:8081uri: 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=1 localhost:10010/api/consumer/findUserById/1 localhost:8081/consumer/findUserById/1
StripPrefix=2 localhost:10010/aa/api/consumer/findUserById/1 localhost: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:8081uri: 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 {@Overridepublic 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*/@Overridepublic 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}.ymlprofile: 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;@AutowiredUserService 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,解决上述问题,实现配置自动更新。

SpringBoot和SpringCloud配置相关推荐

  1. Spring、SpringMVC、SpringBoot、SpringCloud的联系和区别

    一. 上一篇文章刚刚简单介绍了spring框架,下面我将介绍一下Spring,SpringMVC,SpringBoot,SpringCloud的联系和区别. 首先先简单介绍一下各个框架. Spring ...

  2. 【面试题】Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?

    介绍 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.基础版本只有 2 MB 左右的大小,Spring使你能够编写更干净.更可管理.并且更易于测试的代码. SpringMV ...

  3. spring、springMvc、springBoot和springCloud的联系与区别

    作者:尘光掠影  来源:CSDN  原文:https://blog.csdn.net/alan_liuyue/article/details/80656687  spring和springMvc: 1 ...

  4. Springboot 集成Springcloud gateway的入门

    最近做项目使用到了springcloude gateway作为网关,因此在此记录下springcloud gateway的入门操作,后续再将源码解读写出来,先立个flag. 回归正题,Springcl ...

  5. SpringBoot与SpringCloud的关系与区别

    一.SpringBoot和SpringCloud简介 1.SpringBoot:是一个快速开发框架,通过用MAVEN依赖的继承方式,帮助我们快速整合第三方常用框架,完全采用注解化(使用注解方式启动Sp ...

  6. SpringCloud配置中心客户端读取配置

    转载自 SpringCloud配置中心客户端读取配置 微服务连接配置中心来实现外部配置的读取. 引入依赖 <dependencies><dependency><group ...

  7. 再见,Springboot和SpringCloud

    Java中说到微服务肯定离不开Spring Boot和Spring Cloud,这两者到底有什么关系,什么是微服务,如果单纯的说SpringBoot,SpringCloud,都是不准确的,那应该怎么回 ...

  8. 32位数据源中没有mysql_[SpringBoot实战]快速配置多数据源(整合MyBatis)

    前言 由于业务需求,需要同时在SpringBoot中配置两套数据源(连接两个数据库),要求能做到service层在调用各数据库表的mapper时能够自动切换数据源,也就是mapper自动访问正确的数据 ...

  9. Spring、SpringMVC、SpringBoot、SpringCloud的关系分享

    最近在做一些技术架构原型,发现Spring已经跟三四年前发生了很多的区别,技术的迭代日新月异,再不学习就赶不上时代的脚步 ,以下是最近关于Spring.SpringMVC.SpringBoot.Spr ...

最新文章

  1. 转置卷积Transposed Convolution
  2. 实施自动化测试的六个目标和意义
  3. Batch Normalization学习笔记
  4. lvs之 lvs原理架构介绍
  5. 阿里科学家再获世界级荣誉,平头哥首席科学家谢源当选AAASFellow
  6. svn常用命令与分支操作
  7. 程序员不会SQL有多难?高级工程师:可能工作都找不到!
  8. mint java_Oracle Java 12 (JDK 12)在Ubuntu、Linux Mint或Debian(使用PPA)安装配置
  9. bootstrap中日历组件只显示年月
  10. 淘云互动机器人_新时代!新机遇!讯飞淘云2018年全国经销商年终大会隆重召开!...
  11. android intent 视频,Android通过发送Intent播放本地视频和网络视频
  12. 简单的 thymeleaf 前端网页模板
  13. Python设置excel单元格格式
  14. java 自定义表达式_自定义 Java Lambda
  15. 识别图片中的数字------基本思路
  16. 娱美德举办WEMIX空投活动以庆祝《传奇M》在全球发布!
  17. Linux Shell相关记笔记
  18. Schema Compare 使用手册
  19. 三款过CE/FCC/SRCC认证USB接口双频WIFI模块
  20. 移动互联网未来的发展前景

热门文章

  1. ORA-28000 用户被锁解锁
  2. labuladuo算法小抄模板整理
  3. es集群启动失败failed to join
  4. Python中的判断和循环
  5. 基于Html的购物网站的分析与设计
  6. 数字图像处理---空域滤波增强
  7. ORA-01850: 小时值必须介于 0 和 23 之间
  8. 教育中的反思精神——从书籍《创造:一流大学之魂》的一则评论谈起
  9. linux安装2048游戏,如何在CentOS上安装一个2048小游戏
  10. 第三代酷睿i3处理器_酷睿十代可上车!价格公布,附装机神器