为什么要网关
客户端请求服务时,不可能与所有服务一一打交道,应统一请求网关,让网关去请求相关服务。
网关的要素
- 稳定性
- 高可用。一般启动多个zuul,都注册eureka来实现
- 性能,并发性。对于客户端的压力,不能轻易瘫痪,必须保证性能高,并发性高。
- 安全性
- 扩展性
Zuul的特点
- 路由
- 过滤器
Zuul四种过滤器API
- 前置(Pre)
- 限流--流量过大时,根据某种规则阻止多与流量
- 鉴权--权限的鉴定
- 参数校验
- 请求转发
- 路由(Route)
- 后置(Post)
- 请求统计
- 日志
- 错误(Error)
Zuul的生命周期
请求进来,首先经过pre过滤器,对请求的前置加工如参数校验,然后到routing过滤器,将http请求转发到origin server即服务中,可以在此重写http请求使之更高效更优雅。后到post过滤器,拿到请求结果,对结果进行处理。上述3个过滤器发生任何异常,都会转到error过滤器进行处理。在pre过滤器和post过滤器中,可以自己定制过滤器custom。
集成
一般是新建一个项目做网关
pom引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
配置文件注册eureka,config客户端
后启动类添加注解
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
启动项目,若想访问注册到eureka上的其他项目的接口,则使用
localhost:端口号/eureka注册名/接口路径
来访问
比如我的product服务注册到了eureka,product下有一接口product/list访问商品列表。我的网关端口为9000,则使用
localhost:9000/product/product/list
访问
自定义路由
上边只能通过 eureka注册名/接口 的形式,还是会有些僵硬,可以使用自定义路由的形式访问
bootstrap.yml配置设置
zuul:
routes:
newProduct: #自定义路由的名称,任意
path: /myProduct/** #product/product/list -> myProduct/product/list
serviceId: product #代替的服务名
#简单写法
#product: /myProduct/**
这样就可以了
如果想禁止某些路由的访问,可以
zuul:
routes:
newProduct: #自定义路由的名称,任意
path: /myProduct/** #product/product/list -> myProduct/product/list
serviceId: product #代替的服务名
#简单写法
#product: /myProduct/**
ignored-patterns:
- /product/product/listForOrder
- /myProduct/product/listForOrder
此时三种敏感头
"Cookie", "Set-Cookie", "Authorization"
信息的传递是禁止的,若想接收可通过将 sensitiveHeaders设置为空来解决
zuul:
routes:
newProduct: #自定义路由的名称,任意
path: /myProduct/** #product/product/list -> myProduct/product/list
serviceId: product #代替的服务名
sensitiveHeaders:
动态更新Zuul的配置信息
将以上的配置放在git中
新建一个Zuul的配置文件 ZuulConfiguration
package com.viki.apigateway;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.stereotype.Component;
/**
* @Author Sakura
* @Date 12/11/2019
**/
@Component
public class ZuulConfiguration {
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties(){
return new ZuulProperties();
}
}
或者不新建zuul配置类,直接在启动类中
package com.viki.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties(){
return new ZuulProperties();
}
}