一、OpenFeign 是什么?

前面实现服务间调用的 http 客户端是 RestTemplate

弊端:传参需要手动拼接参数

参数==xx & 参数=xx

{参数:xx,参数:xx}

OpenFeign 是 SpringCloud 提供的声明式 HTTP 客户端,能够使用 SpringMVC 的注解,实现远程服务的调用。

二、OPenFeign 使用方法?

1)加依赖

org.springframework.cloud

spring-cloud-starter-openfeign

2)启动类加

@EnableFeignClients(basePackages = "com.blb.orderservice.client")

2)编写接口

@FeignClient("product-service")

public interface ProductServiceClient {

@GetMapping("product-page")

ResponseEntity> getProductPage(@RequestParam(required = false, defaultValue = "1") Long current, @RequestParam(required = false, defaultValue = "5") Long size);

@PostMapping("product")

ResponseEntity addProduct(@RequestBody SysProduct product);

@PutMapping("product")

ResponseEntity updateProduct(@RequestBody SysProduct product);

@DeleteMapping("product/{id}")

ResponseEntity deleteProduct(@PathVariable Long id);

}

4)使用接口

@Autowared

Feign接口 xxx;

xxx.方法(...)

三、OpenFeign 的优化方式

1)OpenFeign 客户端优化

OpenFeign 默认使用 JDK 自带 HttpConnection 实现 http 调用,不带连接池,资源利用率低

可以选用 OKHttpClient、ApacheHttpClient 或 ApacheHC5 带连接池,效率更高

选用下配置之一

feign.okhttp.enabled=true

feign.httpclient.enabled=true

feign.httpclient.hc5=true

2) 请求响应压缩

将请求和响应数据进行压缩,占用带宽小,速度更快

feign.compression.request.enabled=true

feign.compression.response.enabled=true

feign.compression.request.mime-types=text/xml,application/xml,application/json

feign.compression.request.min-request-size=2048

3)日志跟踪

logging.level.com.blb.orderservice.client.ProductServiceClient: debug

@Configuration

public class FeignConfig {

@Bean

Logger.Level feignLoggerLevel() {

return Logger.Level.FULL;

}

}

NONF 没有,默认

BASIC 基本的方法名、URL、响应码

HEADER 请求和响应头

FULL 完整,包含完整的请求响应报文

4)启动熔断器

feign.hystrix.enabled=true

编写熔断降级类:

@Component

public class ProductServiceClientFackback implements ProductServiceClient{

@Override

public ResponseEntity getProductById(Long id) {

Product product = new Product();

product.setName("降级数据");

return ResponseEntity.ok(product);

}

}

设置降级类

@FeignClient(value = "product-service",fallback = ProductServiceClientFackback.class)

四、OpenFeign 的实现原理?

为什么只用写个接口就能实现远程服务的调用??

需要使用的技术:

1)接口的扫描(JDK 扫描包+反射读取接口信息)

2)接口的实现(JDK 的动态代理,创建接口的实现类返回对象) 动态代理

3)调用的过程

读取 FeignClient 中的服务名,到注册中心查询服务的 IP 和端口

请求编码:将 IP 和端口以及接口定义 URL 和参数拼接起来

使用配置的 HTTP 客户端发送请求,获得响应结果

响应解码:对响应结果进行解码,返回数据

五、Gateway 是什么?

SpringCloud 提供的 APl 网关组件,主要的作用是:统一的路由和鉴权,能够提高微服务系统的安全性

我们可以将微服务的 IP 和端口隐藏起来,唯一暴露出来的就是网关的端口,前端的请求都通过网关网关路由到每个微服务

六、Gateway 的入门

1)新建微服务项目

2)注册到 nacos 上

3)配置路由规则

七、Gateway 的路由规则?

重点: 导入 Gateway 依赖,一定不要引入 springMVC 的依赖,会造成冲突

配置路由规则实现请求的转发

spring:

cloud:

gateway:

routes:

- id: 路由名称

uri: 转发的地址

predicates:

- 谓词条件

案例1: cookie中包含某个值就进行路由

spring:

cloud:

gateway:

routes:

- id: after_route

uri: https://example.org

predicates:

- Cookie=mycookie,mycookievalue

案例2:按时间前后转发

spring:

cloud:

gateway:

routes:

- id: after_route

uri: https://example.org

predicates:

- After=2017-01-20T17:42:47.789-07:00[America/Denver]

spring:

cloud:

gateway:

routes:

- id: after_route

uri: https://example.org

predicates:

- Before=2017-01-20T17:42:47.789-07:00[America/Denver]

spring:

cloud:

gateway:

routes:

- id: between_route

uri: https://example.org

predicates:

- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

案例3:按请求方法转发

spring:

cloud:

gateway:

routes:

- id: method_route

uri: https://example.org

predicates:

- Method=GET,POST

案例4:按路径转发某个服务

spring:

cloud:

gateway:

routes: # 路由规则

- id: product-service-route # 路由名称

uri: lb://product-service # 路由的服务

predicates: # 包含路径

- Path=/product/**,/products/**,/product-page/**

八、Gateway 的过滤器?

Gateway 网关可以通过过滤器对请求进行权限验证

Gateway 运行的过程:

1)客户端发送请求给 Gateway

2)Gateway 将请求交给处理器映射

3)处理器映射通过路由规则找到处理器

4)处理器将请求发送给被代理的服务,请求会经过一个过滤器链

5)过滤器有前置后置两种,前置可以执行逻辑判断,对请求进行拦截

6)后置过滤器可以在响应数据上添加内容或进行日志收集等

过滤器按影响范围分为两种:

1)局部过滤器(影响部分路由)

2)全局过滤器(影响所有路由)

案例:全局过滤器验证 Tocken,验证失败不允许访问服务

/**

* 全局 Token驗證的過濾器

*/

@Component

public class TokenFiler implements GlobalFilter, Ordered {

/**

* 過濾

*

* @param exchange

* @param chain

* @return

*/

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

// 獲得請求和響應

ServerHttpRequest request = exchange.getRequest();

ServerHttpResponse response = exchange.getResponse();

// 獲得 token參數

String token = request.getQueryParams().getFirst("token");

// 驗證token,成功就放行

if ("123456".equals(token)) {

// 放行

return chain.filter(exchange);

}

// 设置401响应代码

response.setStatusCode(HttpStatus.UNAUTHORIZED);

response.getHeaders().add("Content-Type", "text/html;charset=UTF-8");

// 保证响应信息

DataBuffer wrap = response.bufferFactory().wrap("验证错误,需要登录".getBytes(StandardCharsets.UTF_8));

// 返回参数给客户端

return response.writeWith(Mono.just(wrap));

}

@Override

public int getOrder() {

// 值越大,過濾器執行越靠後

return 0;

}

}

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: