您的位置:首页 > 编程语言 > Java开发

Spring Cloud Zuul - API网关服务

2018-03-15 11:20 1136 查看

Spring Cloud Zuul - API网关服务

解决微服务中前置校验【冗余】的问题。

可以将于业务无关的校验等剥离出独立项目,由Zuul进行统一调用前置过滤拦截请求。【感觉有点像AOP,不过这个级别就大了】

基础搭建

创建新项目feign-consumer

pom.xml

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


主类注释:

@EnableZuulProxy
@SpringCloudApplication
public class FeignConsumerApplication {

public static void main(String[] args) {
SpringApplication.run(FeignConsumerApplication.class, args);
}
}


配置文件:

spring.application.name=api-getaway
server.port=5555

eureka.client.service-url.defaultZone=http://localhost:1111/eureka/

#传统配置 并不适用
#zuul.routes.api-a-url.path=/api-a-url/**
#zuul.routes.api-a-url.url=http://localhost:8080/

# 面向服务路由 e.g. http://localhost:5555/api-a/hello  会跳转到 hello-server/hello  http://localhost:1234/hello【hello-server地址】 zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=hello-service

zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=feign-consumer

#另一种写法【一样的效果】
#zuul.routes.hello-service=/api-a/**


到这里已经完成了,简单的API面向服务的路由配置跳转。

e.g. http://localhost:5555/api-a/hello 会跳转到 hello-server/hello 既 http://localhost:1234/hello【hello-server地址】

请求过滤 【核心功能】

栗子:

AccessFilter:

public class AccessFilter extends ZuulFilter{

/*过滤类型,决定在请求的哪个阶段执行,pre表示被路由之前执行*/
/* pre:路由前 ; routing :路由请求时 ; post :在routing 和 error 之后 ; error:处理请求时发生错误时 ;*/
@Override
public String filterType() {
return "pre";
}

/*过滤器的执行顺序,根据返回值依次执行*/
@Override
public int filterOrder() {
return 0;
}

/*判断过滤器是否需要执行*/
@Override
public boolean shouldFilter() {
return true;
}

/*过滤器具体逻辑代码*/
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();

4000
//log.info("send {} request tpo {}",request.getMethod(),request.getRequestURL().toString());
System.out.println("send {"+request.getMethod()+"} request tpo {"+request.getRequestURL().toString()+"}");
Object accessToken = request.getParameter("accessToken");
if (accessToken == null){
ctx.setSendZuulResponse(false);  /*设置不进行路由*/
ctx.setResponseStatusCode(401); /*设置返回错误码*/
return null;
}
System.out.println("access token ok");
return null;
}
}


主类【增加】:

@Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}


OK 这样就可以了。http://localhost:5555/api-a/hello?accessToken=11111 访问这个地址才会进行路由

如果没有参数?accessToken=11111 则不进行路由 ,返回错误码401 【HTTP ERROR 401】

默认路由配置

在所有都没有配置的情况下,Zuul是会自动进行路由的。默认的规则是

zuul.routes.hello-service=/hello-service/**


所以默认情况下【不进行路由配置】,测试的项目http://localhost:5555/hello-service/hello?accessToken=11111 这个是可以被路由的

为此,如果不想进行自动路由,则需要使用 一下配置:

zuul.ignored-services=*  #b表示对所有路由都不自动创建路由规则
zuul.ignored-patterns = /**/hello/**  # 不对此规则地址进行路由  【忽略表达式】


自定义路由映射规则

比如,要把helloservice-v1,helloservice-v 路由为/v1/helloservice/** 【默认是/helloservice-v/**这个样子的】

需要在主类中添加:

@Bean
public PatternServiceRouteMapper serviceRouteMapper(){
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}");
}


使用的是正则表达式匹配!

路径配置说明:

? 任意单个字符
* 任意多个字符
** 任意数量字符,支持多级目录


由于配置路径取决于规则保存顺序,而由于properties配置内容无法保证有序,为保证优先顺序,需要使用YAML文件配置。

路由前缀

zuul.prefix=/api


Cookie 与头信息

敏感信息

Zuul 在请求路由时,会过滤HTTp请求头信息中的敏感信息。包括:cookie,set-cookid,Authorization,属性,常用于web应用的Spring Security 和 Shiro等安全框架都搞不定,要做一些参数的修改配置。

全局参数为空覆盖默认值:【不推荐使用】
zuul.sensitiveHeaders=
指定路由开启自定义敏感头
zuul.routes.<router>.customSensitiveHeaders=true
将指定路由的敏感头试着为空
zuul.routes.<touter>.sensitiveHeaders=


重定向

Netflix 1.2.x版本配置:
zuul.addHostHeader=true


Hystrix 和 Ribbon 支持

Zuul 本身就有hystrix 和 ribbon 的功能,配置什么的也就那样,这里忽略。。。。。(ノ`Д)ノ

过滤器

zuul 默认就有好多的过滤器,对请求信息进行过滤等操作。

禁用过滤器

zuul.AccessFilter[过滤器名].pre[过滤器类型].disable = true


动态配置 【核心】

这里要用到 Spring Cloud Config 分布式配置中心 还没看,不懂怎么玩 之后再补上

这里加上配置中心之后可以做到动态路由、动态过滤器的

动态路由

在学习了spring-cloud-config 之后,发现其实这个动态路由只要把zuul连到服务架构上,并使用config的远程配置即可。

不同的地方在于,启动类要添加一下东东,其他地方与正常的config-client一样了

@Bean
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties(){
return  new ZuulProperties();
}


动态过滤器

> 这个要使用到zull,eureka,groovy 来配置,感觉好麻烦,需要使用的时候再研究好了


小杭 20180314
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring cloud zuul api