例子下载:https://download.youkuaiyun.com/download/spark_guo/10515347
在Spring cloud中提供了基于Netflix Zuul实现的API网关组件-spring cloud zuul
1、对于路由规则与服务实例的维护问题。Spring cloudzuul通过与spring cloud Eureka进行整合将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其它微服务的实例信息。
这样的设计非常巧妙地将服务治理体系中维护的实例信息利用起来,使得维护服务实例的工作交给了服务治理
框架自动完成,不再需要人工介入。
对于路由规则的维护,zuul默认会将通过以服务名作为ContextPath的方式来创建路由映射,
大部分情况下,这样默认设置已经可以实现我们大部分的路由需求。
2、对于类似签名校验、登录校验在微服务架构中的冗余问题。spring cloud zuul提供了一套过滤机制,可以很好地
支持这样的任务。开发者可以通过使用zuul来创建各种校验过滤器,然后指定哪些规则的请求需要执行校验逻辑,
只有通过校验的才会被路由到具体的微服务接口,不然就返回错误提示
spring cloud zuul的另外一个核心功能:请求过滤。
zuul允许开发者在API网关上通过定义过滤器来实现对请求的拦截与过滤。只需要继承ZuulFilter抽象类并实现它定义
http://localhost:5555/api-a/hello
http://localhost:5555/api-a/hello?accessToken=Token
主要的类启动:
使用@EnableZuulProxy标签
package com.ultimate.api_gateway;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import com.filter.AccessFilter;
@EnableZuulProxy
@SpringBootApplication
public class Application
{
public static void main( String[] args )
{
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
@Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}
}
AccessFilter
package com.filter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
/**
* @author 作者 E-mail:
* @version 创建时间:2018年7月3日 上午9:35:01
* 类说明
*/
public class AccessFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());
Object accessToken = request.getParameter("accessToken");
if(accessToken == null){
log.warn("access token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
return null;
}
log.info("access token ok");
return null;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
}
application.properties
spring.application.name=api-gateway
server.port=5555
eureka.client.service-url.defaultZone=http://localhost:3333/eureka/
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=ribbon-consumer
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=feign-consumer