feign(组件)
Ribbon是一个基于HTTP和TCP客户端的负载工具,他可以在客户端配置服务端列表,模拟http请求。
Feign集成了Ribbon,并进行了改进,采用接口的方式调用了远程方法。
基于feign调用远程微服务接口
1、导入feign依赖
<!--springcloud整合openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、配置需要调用的feign接口,有点像service层。
/**
* @author zcl
* @create 2021/6/17 20:40
* @desc 商品服务feign
**/
//声明需要调用的微服务的名称
@FeignClient(name = "productserver")
public interface ProductFeign {
/**
* 配置需要访问的微服务接口
* @param pId
* @return
*/
@RequestMapping(value = "queryPnameByPid",method = RequestMethod.GET)
public String queryPnameByPid(@RequestParam("pId") String pId);
}
3、在启动类上激活feign @EnableFeignClients
/**
* @author zcl
* @create 2021/6/14 22:28
* @desc 服务消费者
**/
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
4、通过接口调用远程微服务
@RestController
@RequestMapping(value = "/order")
public class ProConsumerController {
@Autowired
private DiscoveryClient discoveryClient;//获取服务元数据信息对象
@Autowired
private ProductFeign productFeign;
/**
* 基于feign调用远程微服务接口
* 1、导入feign依赖
* 2、配置需要调用的feign接口,有点像service层。
* 3、在启动类上激活feign @EnableFeignClients
* 4、通过接口调用远程微服务
*/
@RequestMapping(value = "/find4", method = RequestMethod.GET)
public String queryPnameByPid4( String pId) {
String s = productFeign.queryPnameByPid(pId);
return s;
}
feign的请求压缩
feign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗,在配置文件中配置如下即可:
feign:
compression:
request:
enabled: true #开启请求压缩
mime-types: application/json,text/html #设置压缩的数据类型
min-request-size: 2048 #设置触发压缩的最小下限
response:
enabled: true #开启响应压缩
feign的日志输出
NONE:不输出日志(性能高) BASIC:适用于生产环境的问题追踪
HEADERS:在BASIC的基础上记录请求和响应头信息 FULL:记录所有
client:
config:
productserver: #指明查看服务日志名称
loggerLevel: FULL
雪崩效应:
A调用B,B调用C,BC之间是强依赖,B需要等待C的响应,C因为种种原因,没有及时响应,造成请求堆积,A又一直在请求B,所有B挂掉,最后A挂掉。这就是雪崩效应。
解决雪崩效应有两种方案,一、服务隔离(服务之间解耦) 二、熔断处理(熔断器Hystrix)三、服务限流
Hystrix组件(断路器)
Springcloud组件之一,是一个使用简单、功能强大的容错工具。
使用:
1、依赖,feign中集成了断路器依赖
2、在feign中开启配置Hystrix
feign:
#开启hystrix
hystrix:
enabled: true
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #默认连接超时时间为1秒
3、自定义一个接口的实现类,在这个实现类中配置熔断触发的逻辑
/**
* @author zcl
* @create 2021/6/19 19:18
* @desc 熔断处理类
**/
@Component
public class ProductFeignClientImpl implements ProductFeignClient {
@Override
public String queryPnameByPid(String pId) {
return "触发熔断";
}
}
4、修改feignclient接口添加降级方法的支持
/**
* @author zcl
* @create 2021/6/17 20:40
* @desc 商品服务feign
**/
//声明需要调用的微服务的名称
@FeignClient(name = "productserver",fallback = ProductFeignClientImpl.class)
public interface ProductFeignClient {
/**
* 配置需要访问的微服务接口
* @param pId
* @return
*/
@RequestMapping(value = "queryPnameByPid",method = RequestMethod.GET)
String queryPnameByPid(@RequestParam("pId") String pId);
}
Hystrix的状态:
1、关闭:所有请求都可以正常访问
2、开启:所有请求都会进入到断路器中
3、半开:维持开启状态一段时间,如果请求响应成功就将状态改为关闭(配置文件配置)
网关(组件)
ZUUL、SpringCloudGateWay(主流)
一、ZUUL
核心功能:请求路由和过滤
基础路由配置:
server:
port: 8180
spring:
application:
name: zuulserver # 应用名称,会在Eureka中显示
#路由配置
zuul:
routes:
#商品服务
#路由id,自定义
productserver:
path: /productserver/** #映射路径
url: http://127.0.0.1:8099 #映射地址
面向服务路由:
面向服务路由比基础路由更加灵活,与eureka集成,服务id直接读取eureka中的配置。
使用:
1、添加eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、开启注册中心服务
@SpringBootApplication
//开启网关功能
@EnableZuulProxy
//eureka的服务发现
@EnableEurekaClient
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
3、在zuul网关服务器配置路由信息以及Eureka信息
server:
port: 8180
spring:
application:
name: zuulserver # 应用名称,会在Eureka中显示
#路由配置
zuul:
routes:
#商品服务
#路由id,自定义
productserver:
path: /productserver/** #映射路径
# url: http://127.0.0.1:8099 #映射地址
serviceId: productserver #从euraka获取服务器id
#eureka配置
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8090/eureka/
instance:
prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
注意:
1、路由id与Eureka服务名一致就可以简写,直接写映射路径
2、zuul中的默认路由配置,路由id为映射路径,也就是路由id与注册中心上的服务名称一致,就可以不写配置文件
2、ZuulFilter(过滤)
类似于Serlevt的过滤器
/**
* @author zcl
* @create 2021/6/20 21:13
* @desc 登录过滤器
**/
@Component
public class LoginFilter extends com.netflix.zuul.ZuulFilter {
/**
* 设置过滤器类型
* 1、pre 请求之前执行
* 2、routing 路由之前执行
* 3、post 路由之后拿到响应结果执行
* 4、error 异常执行
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* 指定过滤器的优先级
* @return
*/
@Override
public int filterOrder() {
return 1;
}
/**
* 当前过滤器是否生效
* @return
*/
@Override
public boolean shouldFilter() {
return true;//true使用
}
/**
* 执行过滤器中的业务
* 登录验证
* 1、根据RequestContext上下文对象获取请求中的asscesstoken
* 2、判断token是否为空 为空就拦截返回错误信息,否则放行
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String asscesstoken = request.getParameter("asscesstoken");
if(StringUtils.isEmpty(asscesstoken)){
currentContext.setSendZuulResponse(false);//拦截请求
currentContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());//返回错误码
}
return null;//返回Null就是放行
}
}
二、GateWay
基础路由配置
1、导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
2、配置启动类
/**
* @author zcl
* @create 2021/6/21 20:55
* @desc GateWay网关启动类
**/
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
}
3、编写配置文件
server:
port: 8150
spring:
application:
name: gatewayserver # 应用名称,会在Eureka中显示
#配置GateWay路由
cloud:
gateway:
routes:
- id: productserver #路由id
uri: http://127.0.0.1:8099 #映射地址
predicates:
- Path=/queryPnameByPid/** #映射路径 访问方式:http://127.0.0.1:8150/queryPnameByPid?pId=1
动态路由配置
server:
port: 8150
spring:
application:
name: gatewayserver # 应用名称,会在Eureka中显示
#配置GateWay路由
cloud:
gateway:
routes:
- id: product_server #路由id,保持唯一
# uri: http://127.0.0.1:8099 #映射地址
uri: lb://productserver #映射地址 lb:根据euraka上的服务名称获取请求路径
predicates:
- Path=/product_server/** #映射路径 访问方式:http://127.0.0.1:8150/queryPnameByPid?pId=1
filters: #配置过滤器
- RewritePath=/product_server/(?<segment>.*),/$\{segment} #路径重写过滤器,将productserver置为空
#eureka配置
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8090/eureka/
instance:
prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
注意:亲身采坑 uri和predicates的映射路径如果一致,会404
原因请看这篇博客https://blog.csdn.net/lizz861109/article/details/105972415