spring cloud(二)

1. Feign应用

Feign的作用;使用Feign实现consumer-demo代码中调用服务

  1. 导入启动器依赖;
  2. 开启Feign功能;
  3. 编写Feign客户端;
  4. 编写一个处理器ConsumerFeignController,注入Feign客户端并使用;
  5. 测试
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

@SpringCloudApplication
@EnableFeignClients
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate get(){return new RestTemplate();}
}
@FeignClient("user-service")
public interface UserClient {@GetMapping("/user/{id}")User get(@PathVariable long id);
}
@RestController
@RequestMapping("/cf")
public class ConsumerFeignController {@Autowiredprivate UserClient userClient;@GetMapping("/{id}")public User get(@PathVariable long id){return userClient.get(id);}
}

Feign主要作用:自动根据参数拼接http请求地址。

2. Feign负载均衡及熔断

目标:可以配置Feign内置ribbon配置项和Hystrix熔断的Fallback配置

分析

  • 负载均衡
  • 服务熔断
  • 请求压缩
  • 日志级别
ribbon:ConnectTimeout: 1000 # 连接超时时长ReadTimeout: 2000 # 数据通信超时时长MaxAutoRetries: 0 # 当前服务器的重试次数MaxAutoRetriesNextServer: 0 # 重试多少次服务OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试
feign:hystrix:enabled: true # 开启Feign的熔断功能compression:request:enabled: true # 开启请求压缩mime-types: text/html,application/xml,application/json # 设置压缩的数据类型min-request-size: 2048 # 设置触发压缩的大小下限response:enabled: true
logging:level:com.gogo: debug
@Component
public class UserClientFallback implements UserClient{@Overridepublic User get(long id) {User user = new User();user.setId(id);user.setName("异常用户");return user;}
}
@Configuration
public class FeignConfig {@BeanLogger.Level logLevel(){return Logger.Level.FULL;}}
@FeignClient(value = "user-service",fallback = UserClientFallback.class,configuration = FeignConfig.class)
public interface UserClient {@GetMapping("/user/{id}")User get(@PathVariable long id);
}

Spring Cloud Gateway的核心就是一系列的过滤器,可以将客户端的请求转发到不同的微服务。主要作用:过滤和路由。

4. Spring Cloud Gateway入门

需求:通过网关系统heima-gateway将包含有 /user 的请求 路由到 http://127.0.0.1:9091/user/用户id

实现步骤:

  1. 创建工程;
  2. 添加启动器依赖;
  3. 编写启动引导类和配置文件;
  4. 修改配置文件,设置路由信息;
  5. 启动测试
    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies>
server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: http://127.0.0.1:9091predicates:- Path=/user/**eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: true

5. 面向服务的路由

使用在eureka注册的服务作为路由地址

如果将路由服务地址写死明显是不合理的;在Spring Cloud Gateway中可以通过配置动态路由解决。

面向服务的路由;只需要在配置文件中指定路由路径类似: lb://user-service

lb 之后编写的服务名必须要在eureka中注册才能使用

server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/**filters:# 添加请求路径的前缀- PrefixPath=/usereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: true

6. 路由前缀处理

可以对请求到网关服务的地址添加或去除前缀

提供服务的地址:http://127.0.0.1:9091/user/8

  • 添加前缀:对请求地址添加前缀路径之后再作为代理的服务地址;

http://127.0.0.1:10010/8 --> http://127.0.0.1:9091/user/8 添加前缀路径/user

  • 去除前缀:将请求地址中路径去除一些前缀路径之后再作为代理的服务地址;

http://127.0.0.1:10010/api/user/8 --> http://127.0.0.1:9091/user/8 去除前缀路径/api

server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/**filters:# 添加请求路径的前缀- PrefixPath=/usereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: true
          filters:# 添加请求路径的前缀- StripPrefix=1

客户端的请求地址与微服务的服务地址如果不一致的时候,可以通过配置路径过滤器实现路径前缀的添加和去除。

7. 过滤器简介

  • 用法:在配置文件中指定要使用的过滤器名称;
  • 类型:局部、全局;
  • 使用场景:请求鉴权、异常处理、记录调用时长等。

8. 自定义局部过滤器

按照默认过滤器编写并配置一个自定义局部过滤器,该过滤器可以通过配置文件中的参数名称获取请求的参数值

需求:在过滤器(MyParamGatewayFilterFactory)中将http://localhost:10010/api/user/8?name=itcast中的参数name的值获取到并输出到控制台;并且参数名是可变的,也就是不一定每次都是name;需要可以通过配置过滤器的时候做到配置参数名。

实现步骤:

  1. 配置过滤器;
  2. 编写过滤器;
  3. 测试
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/api/user/**filters:# 添加请求路径的前缀- StripPrefix=1- My=namedefault-filters:- AddResponseHeader=X-Response-Default-MyName, gogo
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.config> {public static final String PARAM_NAME = "param";@Overridepublic GatewayFilter apply(config config) {return ((exchange, chain) -> {ServerHttpRequest request = exchange.getRequest();if(request.getQueryParams().containsKey(config.param))request.getQueryParams().get(config.param).forEach(var-> System.out.println(config.param+var));return chain.filter(exchange);});}public MyGatewayFilterFactory() {super(config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList(PARAM_NAME);}@Datapublic static class config{String param;}
}

9. 自定义全局过滤器

定义一个全局过滤器检查请求中是否携带有token参数

需求:编写全局过滤器,在过滤器中检查请求地址是否携带token参数。如果token参数的值存在则放行;如果token的参数值为空或者不存在则设置返回的状态码为:未授权也不再执行下去。

实现步骤:

  1. 编写全局过滤器;
  2. 测试
@Componentpublic class MyGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {System.out.println("全局------------------");String token = exchange.getRequest().getQueryParams().getFirst("token");if(StringUtils.isBlank(token)){exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}@Overridepublic int getOrder() {return 1;}
}

10. Gateway其它配置说明

Gateway网关的负载均衡和熔断参数配置

server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/api/user/**filters:# 添加请求路径的前缀- StripPrefix=1- My=namedefault-filters:- AddResponseHeader=X-Response-Default-MyName, gogoglobalcors:corsConfigurations:'[/**]':#allowedOrigins: * # 这种写法或者下面的都可以,*表示全部allowedOrigins:- "http://docs.spring.io"allowedMethods:- GETeureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: truehystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 6000
ribbon:ConnectTimeout: 1000ReadTimeout: 2000MaxAutoRetries: 0MaxAutoRetriesNextServer: 0

Gateway网关一般直接给终端请求使用;Feign一般用在微服务之间调用。

11. Spring Cloud Config分布式配置中心简介

目标:分布式配置中心的作用

小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mg8yPP56-1614310505789)(assets/1560919656472.png)]

spring cloud config作用:可以通过修改在git仓库中的配置文件实现其它所有微服务的配置文件的修改。

12. 搭建配置中心微服务

创建码云的远程公开git仓库,搭建配置中心微服务config-server

  • 创建git仓库:在码云上创建仓库

  • 搭建配置中心config-server:使用spring boot方式搭建和配置

  • 配置中心依赖

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency></dependencies>
  • 配置中心的配置文件
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: trueserver:port: 12000
spring:application:name: config-servercloud:config:server:git:uri: https://gitee.com/Gogo-gitee/config.git

在gitee中修改了配置文件会在配置中心服务及时更新。

13. 获取配置中心配置

需求:将服务提供工程user-service的application.yml配置文件删除,修改为从配置中心config-server中获取。

实现步骤:

  1. 添加启动器依赖;
  2. 修改配置文件;
  3. 启动测试

将原来的application.yml删除;然后添加bootstrap.yml配置文件,该文件也是spring boot的默认配置文件,其内容经常配置一些项目中固定的配置项。如果是项目经常变动的应该配置到application.yml中,现在使用了配置中心则应该配置到git仓库中对于的配置文件。

  • 依赖
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.1.1.RELEASE</version></dependency>
  • 配置文件bootstrap.yml
spring:cloud:config:# 要与仓库中的配置文件的application保持一致name: user# 要与仓库中的配置文件的profile保持一致profile: dev# 要与仓库中的配置文件所属的版本(分支)一样label: masterdiscovery:# 使用配置中心enabled: true# 配置中心服务名service-id: config-servereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka

14. Spring Cloud Bus简介

目标:了解Spring Cloud Bus作用

小结

Spring Cloud Bus作用:将git仓库的配置文件更新,在不重启系统的情况下实现及时同步到各个微服务。

15. Spring Cloud Bus应用

需求:在码云的git仓库中修改user-dev.yml配置文件,实现不重启user-service的情况下可以及时更新配置文件。

实现步骤:

  1. 启动RabbitMQ;
  2. 修改配置中心config-server;
  3. 修改服务提供工程user-service;
  4. 测试
  • config-server的依赖添加内容
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-bus</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream-binder-rabbit</artifactId></dependency>
  • config-server的配置文件添加内容
server:port: 12000
spring:application:name: config-servercloud:config:server:git:uri: https://gitee.com/goheima/heima-config.git# 配置rabbitmq信息;如果是都与默认值一致则不需要配置rabbitmq:host: localhostport: 5672username: guestpassword: guest
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka
management:endpoints:web:exposure:# 暴露触发消息总线的地址include: bus-refresh
  • user-service的依赖添加内容
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-bus</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream-binder-rabbit</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
  • user-service的配置文件添加内容
  # 配置rabbitmq信息;如果是都与默认值一致则不需要配置rabbitmq:host: localhostport: 5672username: guestpassword: guest
  • UserController的修改
@RestController
@RefreshScope
public class HelloController {@Autowiredprivate DataSource dataSource;@AutowiredUserService userService;@Value("${test}")private String test;@GetMapping("/user/{id}")public User query(@PathVariable long id){return userService.queryId(id);}@GetMapping("/hello")public String hello(){return "hello "+test;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391705.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c/c++编译器的安装

MinGW(Minimalist GNU For Windows)是个精简的Windows平台C/C、ADA及Fortran编译器&#xff0c;相比Cygwin而言&#xff0c;体积要小很多&#xff0c;使用较为方便。 MinGW最大的特点就是编译出来的可执行文件能够独立在Windows上运行。 MinGW的组成&#xff1a; 编译器(支持C、…

渗透工具

渗透工具 https://blog.csdn.net/Fly_hps/article/details/89306104 查询工具 https://blog.csdn.net/Fly_hps/article/details/89070552 转载于:https://www.cnblogs.com/liuYGoo/p/11347693.html

numpy 线性代数_数据科学家的线性代数—用NumPy解释

numpy 线性代数Machine learning and deep learning models are data-hungry. The performance of them is highly dependent on the amount of data. Thus, we tend to collect as much data as possible in order to build a robust and accurate model. Data is collected i…

spring 注解方式配置Bean

概要&#xff1a; 再classpath中扫描组件 组件扫描&#xff08;component scanning&#xff09;&#xff1a;Spring可以从classpath下自己主动扫描。侦測和实例化具有特定注解的组件特定组件包含&#xff1a; Component&#xff1a;基本注解。标示了一个受Spring管理的组件&…

主成分分析 独立成分分析_主成分分析概述

主成分分析 独立成分分析by Moshe Binieli由Moshe Binieli 主成分分析概述 (An overview of Principal Component Analysis) This article will explain you what Principal Component Analysis (PCA) is, why we need it and how we use it. I will try to make it as simple…

扩展方法略好于帮助方法

如果针对一个类型实例的代码片段经常被用到&#xff0c;我们可能会想到把之封装成帮助方法。如下是一段针对DateTime类型实例的一段代码&#xff1a;class Program{static void Main(string[] args){DateTime d new DateTime(2001,5,18);switch (d.DayOfWeek){case DayOfWeek.…

零元学Expression Blend 4 - Chapter 25 以Text相关功能就能简单做出具有设计感的登入画面...

原文:零元学Expression Blend 4 - Chapter 25 以Text相关功能就能简单做出具有设计感的登入画面本章将交大家如何运用Blend 4 内的Text相关功能做出有设计感的登入画面 让你五分钟就能快速做出一个登入画面 ? 本章将教大家如何运用Blend 4 内的Text相关功能做出有设计感的登入…

leetcode 395. 至少有 K 个重复字符的最长子串(滑动窗口)

给你一个字符串 s 和一个整数 k &#xff0c;请你找出 s 中的最长子串&#xff0c; 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。 示例 1&#xff1a; 输入&#xff1a;s “aaabb”, k 3 输出&#xff1a;3 解释&#xff1a;最长子串为 “aaa” &…

冠状病毒时代的负责任数据可视化

First, a little bit about me: I’m a data science grad student. I have been writing for Medium for a little while now. I’m a scorpio. I like long walks on beaches. And writing for Medium made me realize the importance of taking personal responsibility ove…

集合_java集合框架

转载自http://blog.csdn.net/zsw101259/article/details/7570033 Java集合框架图 简化图&#xff1a; Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。 1、Java 2集合框架图 ①集合接口&#xff1a;6个…

显示随机键盘

显示随机键盘 1 <!DOCTYPE html>2 <html lang"zh-cn">3 <head>4 <meta charset"utf-8">5 <title>7-77 课堂演示</title>6 <link rel"stylesheet" type"text/css" href"style…

数据特征分析-统计分析

一、统计分析 统计分析是对定量数据进行统计描述&#xff0c;常从集中趋势和离中趋势两个方面分析。 集中趋势&#xff1a;指一组数据向某一中心靠拢的倾向&#xff0c;核心在于寻找数据的代表值或中心值-统计平均数&#xff08;算数平均数和位置平均数&#xff09; 算术平均数…

心学 禅宗_禅宗宣言,用于有效的代码审查

心学 禅宗by Jean-Charles Fabre通过让查尔斯法布尔(Jean-Charles Fabre) 禅宗宣言&#xff0c;用于有效的代码审查 (A zen manifesto for effective code reviews) When you are coding, interruptions really suck.当您编码时&#xff0c;中断确实很糟糕。 You are in the …

leetcode 896. 单调数列

如果数组是单调递增或单调递减的&#xff0c;那么它是单调的。 如果对于所有 i < j&#xff0c;A[i] < A[j]&#xff0c;那么数组 A 是单调递增的。 如果对于所有 i < j&#xff0c;A[i]> A[j]&#xff0c;那么数组 A 是单调递减的。 当给定的数组 A 是单调数组…

数据eda_银行数据EDA:逐步

数据edaThis banking data was retrieved from Kaggle and there will be a breakdown on how the dataset will be handled from EDA (Exploratory Data Analysis) to Machine Learning algorithms.该银行数据是从Kaggle检索的&#xff0c;将详细介绍如何将数据集从EDA(探索性…

结构型模式之组合

重新看组合/合成&#xff08;Composite&#xff09;模式&#xff0c;发现它并不像自己想象的那么简单&#xff0c;单纯从整体和部分关系的角度去理解还是不够的&#xff0c;并且还有一些通俗的模式讲解类的书&#xff0c;由于其举的例子太过“通俗”&#xff0c;以致让人理解产…

计算机网络原理笔记-三次握手

三次握手协议指的是在发送数据的准备阶段&#xff0c;服务器端和客户端之间需要进行三次交互&#xff1a; 第一次握手&#xff1a;客户端发送syn包(synj)到服务器&#xff0c;并进入SYN_SEND状态&#xff0c;等待服务器确认&#xff1b; 第二次握手&#xff1a;服务器收到syn包…

VB2010 的隐式续行(Implicit Line Continuation)

VB2010 的隐式续行&#xff08;Implicit Line Continuation&#xff09;许多情况下,您可以让 VB 后一行继续前一行的语句&#xff0c;而不必使用下划线&#xff08;_&#xff09;。下面列举出隐式续行语法的使用情形。1、逗号“&#xff0c;”之后PublicFunctionGetUsername(By…

flutter bloc_如何在Flutter中使用Streams,BLoC和SQLite

flutter blocRecently, I’ve been working with streams and BLoCs in Flutter to retrieve and display data from an SQLite database. Admittedly, it took me a very long time to make sense of them. With that said, I’d like to go over all this in hopes you’ll w…

leetcode 303. 区域和检索 - 数组不可变

给定一个整数数组 nums&#xff0c;求出数组从索引 i 到 j&#xff08;i ≤ j&#xff09;范围内元素的总和&#xff0c;包含 i、j 两点。 实现 NumArray 类&#xff1a; NumArray(int[] nums) 使用数组 nums 初始化对象 int sumRange(int i, int j) 返回数组 nums 从索引 i …