前言
Zuul API 网关,为微服务应用提供统一的对外访问接口。
Zuul 还提供过滤器,对所有微服务提供统一的请求校验。
引入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
|
配置
- 编辑
application.yml
配置文件,配置路由转发规则
- 以下配置为默认配置,可以不写,根据注册中心自动配置,但是有可能配置不全,所以最好手动配置
1 2 3 4
| zuul: routes: item-service: /item-service/** user-service: /user-service/**
|
启动类
- 启动类添加
@EnableZuulProxy
注解启动Zuul
1 2 3 4 5 6 7
| @EnableZuulProxy @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
|
统一权限校验
- 通过Zuul过滤器,可以判断用户是否有权限访问后台服务,如果没有权限可以阻止用户继续访问
添加过滤器
- 继承
ZuulFilter
类,添加@Component
注解,Zuul会对过滤器自动配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @Component public class AccessFilter extends ZuulFilter {
@Override public String filterType() { return FilterConstants.PRE_TYPE; }
@Override public int filterOrder() { return 6; }
@Override public boolean shouldFilter() {
RequestContext context = RequestContext.getCurrentContext(); String serviceId = (String) context.get(FilterConstants.SERVICE_ID_KEY); return "item-service".equalsIgnoreCase(serviceId); }
@Override public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest();
String token = request.getParameter("token"); if (StringUtils.isBlank(token)) { context.setSendZuulResponse(false);
context.addZuulResponseHeader("Content-Type", "application/json"); context.setResponseBody(JsonResult.err().msg("not login").toString()); } return null; } }
|
Zuul集成Ribbon
- 默认启用Ribbon的负载均衡
- 默认不启用重试,Zuul不推荐启用重试
启用重试
添加依赖
1 2 3 4
| <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
|
配置
- 编辑
application.yml
配置文件,启用Ribbon重试
- 可以配置重试参数,有默认参数,可以根据需要进行调整
Zuul集成Hystrix
添加降级代码
- 实现FallbackProvider接口,在子类中实现降级代码
- Zuul的自动配置,会自动配置降级类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @Component public class ItemFB implements FallbackProvider {
@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 { String json = JsonResult.ok().msg("失败").toString(); return new ByteArrayInputStream(json.getBytes("UTF-8")); }
@Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "application/json;charset=UTF-8"); return headers; } }; } }
|
完成