一 feign
集成了ribbon负载均衡功能,集成了hystrix熔断器功能。支持请求压缩
1 使用feign替代resttemplate发送rest请求
1)在consumer中导入依赖openfeign
2)创建feign客户端,面向接口编程,@feignclient注解,属性赋值服务名;方法上写方法请求映射。feign通过动态代理生成实现类
3) 控制层,注入Feign客户端接口,面向接口编程调用方法实现远程调用服务提供者的对应方法
4)启动类使用 `@EnableFeignClients`注解开启feign
接收路径携带参数变量不能省略赋值,@PathVariable路径变量、@RequestParam请求参数
int login(@RequestParam("s") String s); //这里是参数变量用@RequestParam("s")注解,路径变量则用@PathVariable("s")
//可以传递普通参数,不能传递Java对象,Java对象只能转换为json字符串格式
2 负载均衡
用resttemplate还要加上@loadbalanced注解
配置文件
# 修改服务地址轮询策略,默认是轮询,配置之后变随机
# MaxAutoRetriesNextServer:0 # 最大重试下一个服务次数(集群的情况才会用到,一起来规律是1=2,2 2=2,4 3=4,4 4=4,6 5=6,6)
user-provider:
ribbon:
#轮询
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
ConnectTimeout:10000# 连接超时时间,比如修改服务提供者的ip让你连不上那你消费者肯定连接超时报错
ReadTimeout:2000# 数据读取超时时间,这个是连上服务提供者,然后服务器提供者程序执行超过2秒报错
MaxAutoRetries:1# 最大重试次数(第一个服务),比如连上了,但读取超时再重去尝试读取1次,控制器被访问↓
MaxAutoRetriesNextServer:0# 最大重试下一个服务次数(集群的情况才会用到,一起来规律在上↑)
OkToRetryOnAllOperations:false # 无论是请求超时或者socket read timeout等情况都进行重试
3 熔断器
也就是发生故障不走动态代理生成的实现类,走自定义的接口实现类来降级
1)配置文件开启feign熔断器支持
feign:
hystrix:
enabled:true # 开启Feign的熔断功能
2)熔断降级类
实现接口:自定义方法体。注意实现类需加上@component注解,才能把对象交给spring容器。
也可以采用内部类方式
3)在接口@feignclient注解内给属性fallback赋值来指定降级类
4 feign压缩yml配置
对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。
通过配置开启请求与响应的压缩功能compression:
feign:
compression:
request:
enabled:true# 开启请求压缩
response:
enabled:true # 开启响应压缩
也可对请求数据类型,及触发压缩上下限进行设置
5 feign日志级别配置类
普通日志等级配置
# com.ywj 包下的日志级别都为Debug
logging:
level:
com.ywj: debug
feign日志等级配置。除了使用配置类,也可以在启动类内通过@bean注入给spring容器管理。
@Configuration//配置类注解!
public classFeignConfig {/*** 日志级别
*@return
*/@BeanpublicLogger.Level feignLoggerLevel(){returnLogger.Level.FULL;
}
}
二 spring cloud gateway网关
核心:过滤,路由
同样作为一个微服务,需注册到eureka;工程pom文件导入网关依赖及eureka客户端依赖;启动类添加开启发现客户端注解;配置文件,端口,应用名,eureka地址
1 路由配置
静态路由--动态路由
局部过滤器--全局过滤器
spring:
cloud:
gateway:
routes:
# id唯一标识,可自定义- id: gate-service-route
#路由服务地址
#静态路由策略
# uri: http://localhost:18081
#动态,lb协议表示从Eureka注册中心获取服务请求地址,应该用服务名集群访问,会使用负载均衡访问对应服务,负载均衡LoaderBalance
uri: lb://user-provider
#路由拦截地址配置(断言)
predicates:- Path=/**#注意首字母P要是大写的,2个*
# 配置局部过滤器
filters:
# 请求地址添加路径前缀过滤器
#- PrefixPath=/user
# 去除路径前缀过滤器
- StripPrefix=1
- My
# 配置全局默认过滤器
default-filters:
# 往响应过滤器中加入信息
- AddResponseHeader=X-Response-Default-MyName,ywj
注意:断言,过滤器等关键字key首字母大写。- Path=/** #注意首字母P要是大写的,2个*
2 自定义过滤器
1)全局过滤器
packagecom.zl.filter;importorg.springframework.cloud.gateway.filter.GatewayFilterChain;importorg.springframework.cloud.gateway.filter.GlobalFilter;importorg.springframework.core.Ordered;importorg.springframework.http.HttpStatus;importorg.springframework.stereotype.Component;importorg.springframework.util.StringUtils;importorg.springframework.web.server.ServerWebExchange;importreactor.core.publisher.Mono;
@Component//这个不能少,创建对象才能调用下面的非静态方法↓
public class LoginGlobalFilter implementsGlobalFilter, Ordered {/*** 过滤拦截
*@paramexchange
*@paramchain
*@return
*/@Overridepublic Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) {//获取请求参数//千万不要点错用这个方法String token = request.getQueryParams().get("token").get(0);//NullPointerException,否则出现空指针异常
String token = exchange.getRequest().getQueryParams().getFirst("token");
System.out.println("通过全局过滤器");//如果token为空,则表示没有登录
if(StringUtils.isEmpty(token)){//没登录,状态设置413
exchange.getResponse().setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE);//结束请求
returnexchange.getResponse().setComplete();
}//放行
returnchain.filter(exchange);
}/*** 定义过滤器执行顺序
* 返回值越小,越靠前执行,可以理解为默认从小到大执行
*@return
*/@Overridepublic intgetOrder() {return 0;
}
}
2)局部过滤器
自定义局部拦截器,要注意自定义类的前缀用在配置文件,后缀必须是指定工厂后缀
packagecom.zl.filter;importorg.springframework.cloud.gateway.filter.GatewayFilter;importorg.springframework.cloud.gateway.filter.GatewayFilterChain;importorg.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;importorg.springframework.http.server.reactive.ServerHttpResponse;importorg.springframework.stereotype.Component;importorg.springframework.util.MultiValueMap;importorg.springframework.web.server.ServerWebExchange;importreactor.core.publisher.Mono;
@Componentpublic class MyGatewayFilterFactory extends AbstractGatewayFilterFactory{publicMyGatewayFilterFactory() {super(MyGatewayFilterFactory.Config.class);
}
@OverridepublicGatewayFilter apply(Config config) {return newGatewayFilter() {
@Overridepublic Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("通过局部过滤器");
MultiValueMap queryParams =exchange.getRequest().getQueryParams();
String token= queryParams.getFirst("token");
ServerHttpResponse response=exchange.getResponse();if (token == null) {returnresponse.setComplete();
}returnchain.filter(exchange);
}
};
}public static classConfig {
}
}