携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
Feign
介绍:Feign是一个http请求的轻量级别的框架,在cloud中又有“伪装”。
1. 远程调用
步骤:
-
创建consumer-service-feign模块
- web/lombok/eureka-client/openfeign
-
在启动类添加
- eurekaclient注解
- 开启feign支持
-
编写配置文件
- 复制consumer-service配置文件,建议修服务的应用名称
-
编写controller、service接口完成调用
-
测试
过程:
-
启动类注解
@SpringBootApplication @EnableEurekaClient //注册到注册中心 @EnableFeignClients //开启feign支持 public class ConsumerServiceFeignApplication { public static void main(String[] args) { SpringApplication.run(ConsumerServiceFeignApplication.class, args); } } -
业务代码
@RestController @RequestMapping("consumer") public class ConsumerController { @Autowired private ConsumerService consumerService; /** * @Author: guodong * @Date: 9:52 2020/9/21 * @Parms [id] * @ReturnType: com.itheima.pojo.User * @Description: 根据id查找用户 */ @GetMapping("findUserById/{id}") public User findUserById(@PathVariable Integer id){ return consumerService.findUserById(id); } } @FeignClient("user-service") public interface ConsumerService { /** * @Author: guodong * @Date: 9:52 2020/9/21 * @Parms [id] * @ReturnType: com.itheima.pojo.User * @Description: 根据id查找用户 * String url = "http://user-service/user/findUserById/" + id; * 注意事项: * 1.feign在使用PathVariable注解时必须显示的声明参数,否则异常 */ @GetMapping("user/findUserById/{id}") User findUserById(@PathVariable("id") Integer id); } -
在测试的过程中发现feign具备了ribbon的功能
2. 熔断支持
步骤:
- 在配置文件中开启熔断器支持
- 编写service的实现类
过程:
-
配置文件开启支持
#开启熔断器支持 feign: hystrix: enabled: true -
实现类
@Component public class ConsumerServiceImpl implements ConsumerService { /* 服务降级方法 */ @Override public User findUserById(Integer id) { User user = new User(); user.setId(id); user.setNote("服务繁忙,请您稍后再试..."); return user; } } -
在service中声明服务降级的类字节码
@FeignClient(value = "user-service",fallback = ConsumerServiceImpl.class) public interface ConsumerService { /** * @Author: guodong * @Date: 9:52 2020/9/21 * @Parms [id] * @ReturnType: com.itheima.pojo.User * @Description: 根据id查找用户 * String url = "http://user-service/user/findUserById/" + id; * 注意事项: * 1.feign在使用PathVariable注解时必须显示的声明参数,否则异常 */ @GetMapping("user/findUserById/{id}") User findUserById(@PathVariable("id") Integer id); }
3. 日志配置
步骤:
- 在配置文件中声明日志级别(info/debug/error)
- 编写feign日志配置类
- 在service中配置feign日志配置类的class字节码(经测试,可以不配置也会生效)
过程:
-
配置文件声明日志级别
#日志级别配置 logging: level: com.itheima: debug -
feign配置类
@Configuration //声明是一个配置类 public class FeignLogConfig { /* logger注意导包---》 import feign.Logger; */ @Bean public Logger.Level configLog(){ return Logger.Level.FULL; } }
二、Gateway
介绍:网关系统,路由(负载)+鉴权。是用于替换zuul(网关),gateway是cloud自己全新的组件。
1. 网关搭建
步骤:
-
创建gateway-service服务
- eureka-client
- gateway
-
配置文件
- 复制配置文件---》修改应用名称
-
在启动类添加注解
- eurekaclient注解
过程:
-
配置文件
server: port: 10010 spring: application: name: gateway-server eureka: client: service-url: defaultZone: http://localhost:8761/eureka -
启动类
@SpringBootApplication @EnableEurekaClient public class GatewayServerApplication { public static void main(String[] args) { SpringApplication.run(GatewayServerApplication.class, args); } } -
注意事项:
- 千万不要选择web依赖,gateway启动时使用的是webful。
2. 网关路由
-
配置文件
server: port: 10010 spring: application: name: gateway-server cloud: gateway: routes: - id: consumer-service-feign-route uri: http://localhost:8081 predicates: - Path=/** eureka: client: service-url: defaultZone: http://localhost:8761/eureka存在问题uri硬编码需要写活------》动态。
3. 动态路由
步骤:
-
创建两个消费者的启动类
-
修改网关配置文件
server: port: 10010 spring: application: name: gateway-server cloud: gateway: routes: - id: consumer-service-feign-route #动态路由通过lb协议可以根据服务的应用名称将服务列表从注册中心获取到本地,然后通过ribbon进行负载 uri: lb://consumer-service-feign #http://localhost:8081 predicates: - Path=/** eureka: client: service-url: defaultZone: http://localhost:8761/eureka
4. 路由前缀
-
添加前缀 + 去除前缀
server: port: 10010 spring: application: name: gateway-server cloud: gateway: routes: - id: consumer-service-feign-route #动态路由通过lb协议可以根据服务的应用名称将服务列表从注册中心获取到本地,然后通过ribbon进行负载 uri: lb://consumer-service-feign #http://localhost:8081 predicates: - Path=/** filters: #添加前缀 - PrefixPath=/consumer #去除前缀 - StripPrefix=1 eureka: client: service-url: defaultZone: http://localhost:8761/eureka
5. 过滤器
server:
port: 10010
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: consumer-service-feign-route
#动态路由通过lb协议可以根据服务的应用名称将服务列表从注册中心获取到本地,然后通过ribbon进行负载
uri: lb://consumer-service-feign #http://localhost:8081
predicates:
- Path=/**
filters:
#添加前缀
- PrefixPath=/consumer
#去除前缀
- StripPrefix=1
#全局过滤器添加响应头
default-filters:
- AddResponseHeader=i-love,itheima
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
6. 自定义过滤器
需求:
判断用户是否有登录?通过token令牌? 从请求数据中获取token参数,判断是否为空?
步骤:
-
创建类实现全局过滤器,Ordered接口
-
重写filter方法
- 获取请求对象
- 从请求对象中获取请求参数token
- 对token进行判空校验
- 如果为空拦截
- 如果不为空放行
-
order方法
- 过滤器优先级别---》数值越小优先级别越高
-
-
返回
过程:
-
@Component public class MyFilter implements GlobalFilter,Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //- 获取请求对象 ServerHttpRequest request = exchange.getRequest(); //- 从请求对象中获取请求参数token String token = request.getQueryParams().getFirst("token"); //- 对token进行判空校验 if(StringUtils.isEmpty(token)){ //token为空 //- 如果为空拦截 ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.UNAUTHORIZED); //401表示无权限访问 //编译返回 return response.setComplete(); } //- 如果不为空放行 return chain.filter(exchange); } /** * @Author: guodong * @Date: 12:16 2020/9/21 * @Parms [] * @ReturnType: int * @Description: 值越小优先级越高,建议值要小于2,因为路由也是一个过滤器,并且路由过滤器的优先级别为2 */ @Override public int getOrder() { return 0; } } - http://localhost:10010/consumer/findUserById/2?token=121546456485