(十)spring-cloud入门学习:API服务网关Spring Cloud Zuul

Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,那外部请求如何调用服务?如何进行路由和过滤?

在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。

Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。

Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。

一、Zuul基础功能:路由和过滤

1.创建eureka_zuul工程,pom.xml如下


  4.0.0

  com.kevin
  euraka_zuul
  0.0.1-SNAPSHOT
  jar

  euraka_zuul
  http://maven.apache.org

  
    UTF-8
  

  
    org.springframework.boot
    spring-boot-starter-parent
    2.1.4.RELEASE
  

  
    
        org.springframework.boot
        spring-boot-starter-web
    
    
        org.springframework.boot
        spring-boot-starter-test
        test
    
    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
    
    
        org.springframework.cloud
        spring-cloud-starter-netflix-zuul
    
  
  
    
        
           org.springframework.cloud
           spring-cloud-dependencies
           Greenwich.SR1
           pom
           import
        
    
  

2. application.properties定义路由地址

spring.application.name=eurekaZuul
server.port=9301
eureka.client.serviceUrl.defaultZone=http://localhost:9101/eureka/
zuul.routes.ribbon.path=/ribbon/**
zuul.routes.ribbon.serviceId=eurekaRibbon
zuul.routes.feign.path=/feign/**
zuul.routes.feign.serviceId=eurekaFeign

3. Application.java开启zuul代理

package com.kevin.euraka_zuul;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class Application {
	
    public static void main( String[] args ) {
    	SpringApplication.run(Application.class, args);
    }
}

4. 如果需要进行过滤,可继承ZuulFilter。
Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”;
(十)spring-cloud入门学习:API服务网关Spring Cloud Zuul_第1张图片

TokenFilter.java:

package com.kevin.euraka_zuul.filter;

import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

@Component
public class TokenFilter extends ZuulFilter{

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        System.out.println(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
        String accessToken = request.getParameter("token");
        if(StringUtils.isEmpty(accessToken)) {
        	ctx.setSendZuulResponse(false);
        	ctx.setResponseStatusCode(400);
        	ctx.setResponseBody("failed, no token");
        }else {
        	ctx.setSendZuulResponse(true);
        	ctx.setResponseStatusCode(200);
        }
		
		return null;
	}

	@Override
	public String filterType() {
		return "pre";
	}

	@Override
	public int filterOrder() {
		return 0;
	}
}

4. 测试:
1)过滤检查
在这里插入图片描述
2)负载均衡
(十)spring-cloud入门学习:API服务网关Spring Cloud Zuul_第2张图片
(十)spring-cloud入门学习:API服务网关Spring Cloud Zuul_第3张图片

3) 路由
在这里插入图片描述

二、熔断

1. 实现熔断类FallbackProvider,需要指定路由应用名和定义熔断返回内容

package com.kevin.euraka_zuul.filter;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

@Component
public class FeignFallback implements FallbackProvider{

	@Override
	public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
		return new ClientHttpResponse() {
			
			@Override
			public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
                  headers.setContentType(MediaType.APPLICATION_JSON);
              	  return headers;
			}
			
			@Override
			public InputStream getBody() throws IOException {
				return new ByteArrayInputStream("The service is unavailable.".getBytes());
			}
			
			@Override
			public String getStatusText() throws IOException {
				return "OK";
			}
			
			@Override
			public HttpStatus getStatusCode() throws IOException {
				return HttpStatus.OK;
			}
			
			@Override
			public int getRawStatusCode() throws IOException {
				return 200;
			}
			
			@Override
			public void close() {
				
			}
		};
	}

	@Override
	public String getRoute() {
		return "eurekaFeign";
	}
}

2. 当eurekaFeign停止服务后,通过zuul访问,返回熔断信息
在这里插入图片描述

三、超时与重试

1. 可以通过以下配置设置超时时长

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
ribbon.ConnectTimeout=3000
ribbon.ReadTimeout=6000

也可以指定service的超时时长
(十)spring-cloud入门学习:API服务网关Spring Cloud Zuul_第4张图片

2. 重试


	org.springframework.retry
	spring-retry

配置文件:

#开启重试
zuul.retryable=true
#最大重试次数
client.ribbon.MaxAutoRetries=3
#切换相同Server的次数
client.ribbon.MaxAutoRetriesNextServer=0

参考:
https://cloud.spring.io/spring-cloud-static/Greenwich.SR1/single/spring-cloud.html#_router_and_filter_zuul
http://www.ityouknow.com/springcloud/2018/01/20/spring-cloud-zuul.html

你可能感兴趣的:(spring-cloud)