2.11、 Feign应用
-
是对下面代码的优化
-
自动根据参数拼接http请求地址
2.11.1、 操作
效果
2.12、Feign负载均衡及熔断
-
Feign集成了ribbon配置项和Hystrix熔断的Fallback配置项,可以使用Feign来配置他。
-
为了方便测试,我们将一切的ribbon配置项和Hystrix项全部注释掉
2.12.1 Feign 负载均衡
2.12.2 Feign 服务熔断
关闭user-service看效果
2.12.3、 请求压缩
feign:
hystrix:
enabled: true # 开启Feign的熔断功能
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
response:
enabled: true # 开启响应压缩
2.12.4、 日志级别
01、Feign 的Level级别
- NONE:不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
02、测试结果
2.13、 Spring Cloud Gateway
- 基于Filter链提供网关基本功能:安全、监控、埋点、限流等。
- 为微服务架构提供简单、有效且统一的API路由管理方式。
- 是替代Netflix Zuul的一套解决方案。
- 组件的核心是一系列的过滤器
- 通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。
- 是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,从
而加强安全保护。
- 本身也是一个微服务,需要注册到Eureka服务注册中心。
- 核心功能
- 过滤
- 路由
2.13.1、 架构
- 不管是来自于客户端(PC或移动端)的请求,还是服务内部调用。一切对服务的请求都可经过网关,然后再由网关来实现鉴权、动态路由等等操作。
- Gateway就是我们服务的统一入口。
2.13.2、 概念
01、路由(route)
- 由一个ID、一个目的URL、一组断言工厂、一组Filter组成。
- 如果路由断言为真,说明请求URL和配置路由匹配。
02、断言(Predicate)
- Spring Cloud Gateway中的断言函数输入类型是Spring 5.0框架中的ServerWebExchange。
- Spring Cloud Gateway的断言函数允许开发者去定义匹配来自于Http Request中的任何
信息比如请求头和参数。
03、过滤器(Filter)
- 一个标准的Spring WebFilter。
- Spring Cloud Gateway中的Filter分为两种类型
- Gateway Filter
- Global Filter。
- 过滤器Filter将会对请求和响应进行修改处理。
2.14、搭建网关服务,实现以下功能
- 搭建gateway-demo
- 将包含有/user的请求路由到user-service服务中
2.14.1、操作
2.14.2、结果
2.14.3、问题
- 我们现在可以直接通过网关访问user-service服务,那么consumer-demo已经没用了,那还需要consumer-demo吗?
- 个人理解consumer-demo已经没有用了。
2.15、面向服务的路由
- 在刚才的路由规则中,把路径对应的服务地址写死了!如果同一服务有多个实例的话,这样做显然不合理。
- 应该根据服务的名称,去Eureka注册中心查找服务对应的所有实例列表,然后进行动态路由!
2.15.1、操作
- lb 之后编写的服务名必须要在eureka中注册才能使用
- 动态路由:lb user-service(服务名)
- gateway将使用 LoadBalancerClient把user-service通过eureka解析为实际的主机和端口,并进行ribbon负载均衡。
2.15.2、结果
- 启动 user-service9091
- 启动 user-service9092
- 启动 gateway-demo
- 启动 eureka-server
2.16、路由前缀处理
- 可以对请求到网关服务的地址添加或去除前缀
2.16.1、添加前缀
- 对请求地址添加前缀路径之后再作为代理的服务地址
- http://127.0.0.1:10010/8 --> http://user-service/user/8
- 前缀路径/user
2.16.2、去除前缀
-
将请求地址中路径去除一些前缀路径之后再作为代理的服务地址
-
http://127.0.0.1:10010/api/user/8 --> http://user-service/user/8
- 去除前缀路径/api
-
通过StripPrefix=n 来指定了路由要去掉的n个前缀,案例
- StripPrefix=1
- http://localhost:10010/api/user/8 --》http://user-servic/user/8
- StripPrefix=2
- http://localhost:10010/api/user/8 --》http://user-servic/8
2.17、Gateway的过滤器
- 命名规则
- XXXXGatewayFilterFactory
2.17.1、Gateway常见自带过滤器
- AddRequestHeader
- 对匹配上的请求加上Header
- AddRequestParameters
- 对匹配上的请求路由添加参数
- AddResponseHeader
- 对从网关返回的响应添加Header
- StripPrefix
- 对匹配上的请求路径去除前缀
2.17.2、过滤器类型
- 局部过滤器
- 通过 spring.cloud.gateway.routes.filters 配置在具体路由下
- 只作用在当前路由上;
- 自带的过滤器都可以配置或者自定义按照自带过滤器的方式。
- 如果配置spring.cloud.gateway.default-filters上会对所有路由生效
- 算是全局的过滤器;
- 实现上都要实现GatewayFilterFactory接口。
- 全局过滤器
- 不需要在配置文件中配置
- 作用在所有的路由上
- 实现 GlobalFilter 接口即可。
2.17.3、执行生命周期
- Gateway的Filter的生命周期也类似Spring MVC的拦截器
- 有两个:“pre"和"post”,分别会在请求被执行前和被执行后调用
- “pre"和"post”,可以通过过滤器的GatewayFilterChain执行filter方法前后来实现。
2.17.4、常见使用场景
- 请求鉴权:
- GatewayFilterChain 执行filter方法前,如果发现没有访问权限,直接就返回空。
- 异常处理:
- GatewayFilterChain执行filter方法后,记录异常并返回。
- 服务调用时长统计
- GatewayFilterChain执行filter方法前后根据时间统计。
2.17.5、配置全局默认过滤器
2.17.6、自定义局部过滤器
结果
package fei.zhou.gatewaydemo.filter;
import java.util.Arrays;
import java.util.List;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
@Component
public class MyParam11GatewayFilterFactory extends AbstractGatewayFilterFactory<MyParam11GatewayFilterFactory.Config> {
static final String PARAM_NAME = "param";
public MyParam11GatewayFilterFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(PARAM_NAME);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// http://localhost:10010/user/8?name=userId config.param ==> name
// 获取请求参数中param对应的参数名 的参数值
ServerHttpRequest request = exchange.getRequest();
if (request.getQueryParams().containsKey(config.param)) {
request.getQueryParams().get(config.param).forEach(
value -> System.out.println("------------局部过滤器-------参数名字:" + config.param + "--参数值:" + value));
}
return chain.filter(exchange);
};
}
public static class Config {
// 对应在配置过滤器的时候指定的参数名
private String param;
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
}
2.17.7、 自定义全局过滤器
- 定义一个全局过滤器检查请求中是否携带有token参数
- 是:通过
- 否:不通过,告诉客户端401提示
package fei.zhou.gatewaydemo.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyGlobal11Filter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("--------------全局过滤器MyGlobal11Filter------------------");
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (StringUtils.isBlank(token)) {
// 设置响应状态码为未授权
// UNAUTHORIZED(401, "Unauthorized"),
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 值越小越先执行
return 1;
}
}
2.17.8、Gateway 负载均衡和熔断
- Gateway中默认集成了Ribbon负载均衡和Hystrix熔断机制。
- 所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议手动进行配置:
hystrix:
command:
default:
execution:
isolation:
thread:
# 服务提供者的超时时间,2秒,如果请求服务提供者超过2秒,就服务降级和线程隔离
timeoutInMilliseconds: 6000
ribbon:
ConnectTimeout: 1000 # 连接超时时长
ReadTimeout: 2000 # 数据通信超时时长
MaxAutoRetries: 0 # 当前服务器的重试次数
MaxAutoRetriesNextServer: 0 # 重试多少次服务
OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试
2.17.9、Gateway 跨域配置
- 一般网关都是所有微服务的统一入口,必然在被调用的时候会出现跨域问题。
- 可以在网关服务器中通过配置解决,允许哪些服务是可以跨域请求的。
01、跨域概念
- 在js请求访问中,如果访问的地址与当前服务器的域名、ip或者端口号不一致则称为跨域请求。
- http://localhost:8080中的js —访问—> http://localhost:9091的数据,因为端口不同,是跨域请求。
- 若不解决则不能获取到对应地址的返回结果。
02、解决跨域的配置
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
#allowedOrigins: * # 这种写法或者下面的都可以,*表示全部
allowedOrigins:
- "http://docs.spring.io"
allowedMethods:
- GET
- 可以允许来自 http://docs.spring.io 的get请求方式获取服务数据。
- allowedOrigins
- 指定允许访问的服务器地址,如http://docs.spring.io。
- ‘[/**]’
- 表示对所有访问到网关服务器的请求地址
2.17.10、 Gateway的高可用
- 启动多个Gateway服务,自动注册到Eureka,形成集群。
- 服务内部访问
- 访问Gateway,自动负载均衡,没问题。
- 外部访问(PC端、移动端…)
- 它们无法通过Eureka进行负载均衡,那么该怎么办?,Gateway怎么高可用?
- 可以使用Nginx来对Gateway进行代理
2.17.11、Gateway与Feign的区别
- Gateway
- 作为整个应用的流量入口,接收所有的请求,如PC、移动端等,并且将不同的请求转发至不同的处理微服务模块,其作用可视为nginx;
- 大部分情况下用作权限鉴定、服务端流量控制
- Feign
- 将当前微服务的部分服务接口暴露出来
- 主要用于各个微服务之间的服务调用
2.18、 Spring Cloud Config分布式配置中心
2.18.1、 分布式配置中心
- 支持配置文件放在配置服务本地
- 也支持放在远程Git仓库(GitHub、码云)
- 项目从配置中心拉取配置
2.18.2、 架构
2.18.3、 搭建配置中心微服务
01、创建码云的远程公开git仓库:spring_cloud_config
02、将user-Service的配置文件放到git仓库中,命名为userService-dev.yml
- 配置文件的2种命名方式
- {application}-{profile}.yml
- {application}-{profile}.properties
- 配置文件说明
- application:为应用名称
- profile:用于区分开发环境,测试环境、生产环境等
- 案例userService-dev.yml
- 微服务user-Service开发环境下使用的配置文件
03、搭建配置中心微服务
结果
2.18.4、 获取配置中心配置
- 改造用户微服务user-service,配置文件信息不再由微服务项目提供,而是从配置中心获取
01、 user-service 操作
- japplication.yml 备份为 application.yml.back
- 删除application.yml文件
- 新增bootstrap.yml文件
spring:
cloud:
config:
# 要与仓库中的配置文件的application保持一致
name: userService
# 要与仓库中的配置文件的profile保持一致
profile: dev
# git仓库中的配置文件所属的分支
label: master
discovery:
# 使用配置中心
enabled: true
# 配置中心服务名
service-id: config-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
结果
2.19、 Spring Cloud Bus
- Spring Cloud Bus是用轻量的消息代理将分布式的节点连接起来,可以用于广播配置文件的更改或者服务的监控管理。
- 也就是消息总线可以为微服务做监控,也可以实现应用程序之间相互通信。
- Spring Cloud Bus可选的消息代理有RabbitMQ和Kafka。
2.19.1、 原先的配置中心修改了配置,不能及时同步到各个微服务
01、git 添加属性
02、user-service 设置打印属性
03、重启user-service 后,请求数据有返回
04、修改git属性,不重启user-service
2.19.2、 git仓库的配置文件更新,在不重启系统的情况下实现及时同步到各个微服务
01、 架构
02、 config-server配置操作
03、 user-service配置操作
04、更新配置
05、发布MQ通知
http://127.0.0.1:12000/actuator/bus-refresh
映射的配置
# 暴露触发消息总线的地址
include: bus-refresh
06、查看结果(有实时更新)
代码地址
https://gitee.com/DanShenGuiZu/spring_cloud_config.git