zuul API网关,为微服务应用提供统一的对外访问接口
zuul 还提供过滤器,对所有微服务提供统一的请求校验
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/**
添加 @EnableZuulProxy
和 @EnableDIscoverClient
注解
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(Sp11ZuulApplication.class, args);
}
}
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
spring:
application:
name: zuul
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
zuul:
retryable: true
# routes:
# item-service: /item-service/**
# user-service: /user-service/**
# order-service: /order-service/**
ribbon:
ConnectTimeout: 1000
ReadTimeout: 1000
MaxAutoRetriesNextServer: 1
MaxAutoRetries: 1
0配置,已经启用了hystrix
降级代码:
实现FallbackProvider
接口,实现降级代码
只需要添加 @Component
注解
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 500
@Component
public class ItemFallback implements FallbackProvider {
/**
* 当前降级类,对那个服务有效
* 如果返回 "item-service" , 那么当前降级类只对商品服务有效
* 如果返回 * 或者null,那么对所有服务都有效
* @return
*/
@Override
public String getRoute() {
return "item-service";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.OK.value();
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.OK.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
// JsonRest : {code:400,msg:"获取商品列表失败!" , data:null}
String s = JsonResult.err().msg("获取商品列表失败!").toString();
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
return in;
}
@Override
public HttpHeaders getHeaders() {
// Content-Type: application-json
HttpHeaders h = new HttpHeaders();
h.setContentType(MediaType.APPLICATION_JSON);
return h;
}
};
}
}
spring:
application:
name: zuul
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
zuul:
retryable: true
ribbon:
ConnectTimeout: 1000
ReadTimeout: 2000
MaxAutoRetriesNextServer: 1
MaxAutoRetries: 1
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 500
http://localhost:3001/item-service/35
添加过滤器,继承ZuulFilter
,按照规则实现过滤方法. 不用做任何配置,只需要添加@Component
注解
@Component
public class AccessFilter extends ZuulFilter {
/**
* 过滤器的类型 : 前置 ,后置, 路由, 错误
* @return
*/
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
/**
* 过滤器添加的位置
* 返回6 ,加到第6个位置
* @return
*/
@Override
public int filterOrder() {
return 6;
}
/**
* 针对当前请求进行判断,判断当前请求是否要执行这个过滤器的过滤代码
* 如果访问 item-service 要检查权限
* 如果访问其他服务则不检查权限,直接访问
* @return
*/
@Override
public boolean shouldFilter() {
RequestContext ctx= RequestContext.getCurrentContext();
//获取当前请求的服务id
String serviceId=(String)ctx.get(FilterConstants.SERVICE_ID_KEY);
if(serviceId.equals("item-service")){
return true;//要执行权限过滤
}
return false;//跳过过滤代码不执行
}
/**
* 过滤代码,对用户权限进行检查
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx= RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if(StringUtils.isEmpty(token)){
//没有token,阻止继续调用
ctx.setSendZuulResponse(false);
//发送提示,提示没有用户登录
ctx.setResponseStatusCode(JsonResult.NOT_LOGIN);
ctx.setResponseBody(JsonResult.err().code(JsonResult.NOT_LOGIN).msg("not login!").toString());
}
return null; //zuul过度设计,返回值在现在的版本中没有使用
}
}