Zuul-项目入口(提供Filter)
环境
加入starter项目依赖:
Zuul和Eureka Discovery Client
yml文件:
spring:
application:
name: zuul\
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
zuul:
routes:
item-service: /item-service/**
user-service: /user-service/**
order-service: /order-service/**
功能
集成Eureka,Ribbon
重试
增加yml配置路由规则
zuul:
retryable: true
ribbon:
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
降级
创建一个降级类,实现FallbackProvider
@Component
public class orderFallback implements FallbackProvider {
/*
* 判断当前调用的后台服务,是否要应用当前降级类的降级代码
*/
@Override
public String getRoute() {
return "item-service";
}
/*
* 设置降级响应,返回包含降级响应数据的对象
*/
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
ClientHttpResponse clientHttpResponse = new ClientHttpResponse() {
@Override
public HttpHeaders getHeaders() {
//Content-Type:application/json
HttpHeaders h = new HttpHeaders();
h.setContentType(MediaType.APPLICATION_JSON);
return h;
}
@Override
public InputStream getBody() throws IOException {
//{code:200, msg:"调用订单服务失败", data:null}
String json = JsonResult.err("调用订单服务失败").toString();
return new ByteArrayInputStream(json.getBytes());
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.OK.getReasonPhrase();//{200,"ok"}--->"ok"
}
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;//{200,"ok"}
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.OK.value();//{200,"ok"}--->200
}
@Override
public void close() {
// TODO Auto-generated method stub
}
};
return clientHttpResponse;
}
}
熔断
默认是10秒20次请求,50%熔断
健康检查(监控)
zuul已经默认包含了actuator的jar包,直接在配置文件配置即可
management:
endpoints:
web:
exposure:
include: hystrix.stream
过滤器*
需要创建一个类继承ZuulFilter
@Component
public class AccessFilter extends ZuulFilter{
/*
* 对当前请求进行判断,判断这次请求是否要执行run方法
* 如果访问的是item-service,执行过滤,判断是否登录
* 如果访问的是其他服务,则跳过过滤代码,继续正常执行流程
*/
@Override
public boolean shouldFilter() {
//获取正在请求的服务ID
RequestContext ctx = RequestContext.getCurrentContext();
String serviceId = (String) ctx.get(FilterConstants.SERVICE_ID_KEY);
if("item-service".equals(serviceId)) {
return true;
}
return false;
}
/*
* 过滤方法,判断用户是否登录,如果没有登录
* 应该阻止用户继续访问
*/
@Override
public Object run() throws ZuulException {
/*
* 先判断请求参数get参数中有没有token
*/
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if(StringUtils.isEmpty(token)) {
//没有token就表示没有登录,阻止继续访问
//不发送Zuul响应
ctx.setSendZuulResponse(false);
//发送未登录响应
ctx.setResponseBody(JsonResult.err("not login").code(JsonResult.NOT_LOGIN).toString());
ctx.setResponseStatusCode(JsonResult.NOT_LOGIN);
}
return null; //zuul当前版本没有启用返回值
}
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return 6; //在第5个过滤器中,在Context上下文对象中添加了serviceId,5之前就无法访问到serviceId
}
}