微服务网关
微服务网关是介于客户端与服务器端的中间层,所有外部请求先经过网关。
微服务网关封装了应用程序的内部结构,客户端只用跟网关交互,而无需直接调用特定的微服务接口
Zuul简介
Zuul可以通过加载动态过滤机制,从而实现以下各项功能:
1.验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。
2.审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。
3.动态路由: 以动态方式根据需要将请求路由至不同后端集群处。
4.压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。
5.负载分配: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。
6.静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。
7.多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。
编写Zuul微服务网关
创建一个子项目
添加pom.xml依赖
<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>
启动类添加注解@EnableZuulProxy
@SpringBootApplication
@EnableZuulProxy //声明一个Zuul代理
public class YmkGetewayZuulApplication {
public static void main(String[] args) {
SpringApplication.run(YmkGetewayZuulApplication.class, args);
}
}
修改application,yml
server:
port: 8040
spring:
application:
name: gateway-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
security:
enabled: false
一个简单的微服务网关就完成了,有配置可知道,添加了Zuul的依赖,并注册到Eureka Server上。
默认情况下,Zuul会代理所有注册到Eureka Server上的微服务,并且Zuul的路由规则如下:http://zuul_host:zuul_port/微服务的serviceId/**
访问 :http://localhost:8040/feign-consumer/feign/hello?name=feign
路由配置下详解
前文已经编写了一个简单的Zuul网关,并让网关代理了所有注册到Eureka Server的微服务,但是现实中可能只想Zuul代理部分微服务,又或者需要对URL的路由配置。
1、自定义指定微服务的访问路径
zuul:
routes:
feign-consumer: /test/**
访问:http://localhost:8040/test/feign/hello?name=feign
2、忽略指定微服务
忽略多个微服务,逗号分隔即可
zuul:
ignored-services: feign-consumer
3、忽略所有的服务,只路由指定的服务
zuul:
ignored-services: '*' # 使用'*'可忽略所有微服务
routes:
feign-consumer: /user/**
4、同时指定微服务的serviceId和对应路径
zuul:
routes:
user-route: # 该配置方式中,user-route只是给路由一个名称,可以任意起名。
service-id: feign-consumer
path: /user/** # service-id对应的路径
跟实例1一样的效果
5、同时指定path和url
zuul:
routes:
user-route: # 该配置方式中,user-route只是给路由一个名称,可以任意起名。
url: http://localhost:8000/ # 指定的url
path: /user/** # url对应的路径。
这样就可以将/user/** 映射到http://localhost:8000/**。这种方式配置的路由不会作为HystrixCommand执行,同时也不能用Ribbon来负载均衡多个URL。实例6可解决该问题。
6、同时指定path和url,并且不破坏Zuul的Hystrix,Bibbon特性。
zuul:
routes:
user-route:
path: /user/**
service-id: feign-consumer
ribbon:
eureka:
enabled: false # 禁用掉ribbon的eureka使用。
feign-consumer:
ribbon:
listOfServers: localhost:8000,localhost:8001
7、路由前缀
zuul:
prefix: /api
routes:
feign-consumer: /test/**
8、忽略某些路径
zuul:
ignoredPatterns: /**/admin/** # 忽略所有包括/admin/的路径
routes:
feign-consumer: /user/**
9、本地转发
zuul:
routes:
route-name:
path: /path-a/**
url: forward:/path-b
这样访问,Zuul的path/a/**路径,将转发到path/b/**
Zuul过滤器
过滤器是zuul的核心组件,过滤器可以说是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端
zuul定义了4中标准过滤器
pre:可以在请求被路由之前调用。
routing:在路由请求时候被调用。
post:在routing和error过滤器之后被调用。
error:处理请求时发生错误时被调用。
编写一个过滤器
新建过滤器类
public class PermisFilter extends ZuulFilter {
@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();
String login = request.getParameter("login");
if (login == null) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");
ctx.setResponseBody("非法访问");
}
return null;
}
}
filterType:该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了四种不同生命周期的过滤器类型
filterOrder:通过int值来定义过滤器的执行顺序,数值越小优先级越高。
shouldFilter:返回一个boolean类型来判断该过滤器是否要执行。我们可以通过此方法来指定过滤器的有效范围。
run:过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等
在启动类,添加过滤器
@SpringBootApplication
@EnableZuulProxy //声明一个Zuul代理
public class YmkGetewayZuulApplication {
public static void main(String[] args) {
SpringApplication.run(YmkGetewayZuulApplication.class, args);
}
//配置过滤器Bean
@Bean
PermisFilter permisFilter() {
return new PermisFilter();
}
}
访问:http://localhost:8040/test/feign/hello?name=feign2
添加login参数 http://localhost:8040/test/feign/hello?name=feign2&login=asdf
源码下载 : https://download.csdn.net/download/u013083284/10763720