Spring cloud学习--Zuul01
Zuul解决的问题
- 作为系统的统一入口,屏蔽了系统内部各个微服务的细节
- 可以与微服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发
- 实现接口权限校验与微服务业务逻辑的解耦
搭建Zuul服务
zuul maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
spring-cloud-starter-zuul包含zuul-core、spring-cloud-starter-hystrix、spring-cloud-starter-ribbon、spring-cloud-starter-actrator
主类上开启API网关服务功能
//@SpringCloudApplication = @SpringBootApplication + @EnableDiscoveryClient + @EnableCircuitBreaker
@EnableZuulProxy
@SpringCloudApplication
public class ApiGatewayApplication
{
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
配置application.properties
spring.application.name=api-gateway
server.port=5555
实现简单的传统路由转发功能
只需要加入
#实现传统的路由转发功能
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:8080/
所有符合/api-a-url/**规则的访问都将被路由转发到http://localhost:8080/地址上,也就是说当我们访问http://localhost:5555/api-a-url/hello的时候,
API网关服务会将该请求路由到http://localhost:8080/hello提供的微服务上
面向服务的路由
- 加入Eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- 配置路由
spring.application.name=api-gateway
server.port=5555
#实现传统的路由转发功能
#zuul.routes.api-a-url.path=/api-a-url/**
#zuul.routes.api-a-url.url=http://localhost:8080/
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=eureka-client
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=feign-consumer
#eureka.instance.hostname=localhost
#注册服务的注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
注意与传统路由的区别,一个是面向url的,一个是面向服务的
- 启动eureka-server、eureka-client、feign-consumer、api-gateway服务
访问http://localhost:5555/api-a/hello、http://localhost:5555/api-b/feign-consumer,可以访问http://localhost:2001/hello和http://localhost:9001/hello服务
请求过滤
请求过滤解决的问题
- 将鉴权校验的非业务部分剥离出来,形成独立的业务服务
- 微服务中不需要调用此业务服务进行鉴权校验
简单的示例
- 创建过滤器
public class AccessFilter extends ZuulFilter
{
private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
//filterType:过滤器的类型,他决定过滤器会在请求的哪个生命周期中执行,pre代表会在请求被路由之前执行
@Override
public String filterType()
{
return "pre";
}
//filterOrder过滤器执行顺序
@Override
public int filterOrder()
{
return 0;
}
//shouldFilter执行生效的条件
@Override
public boolean shouldFilter()
{
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(null == accessToken)
{
log.warn("access token is empty.");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
return null;
}
log.info("access token ok.");
return null;
}
}
- 在主类中创建具体的bean,实例化过滤器
@EnableZuulProxy
@SpringCloudApplication
public class ApiGatewayApplication
{
@Bean
public AccessFilter accessFilter()
{
return new AccessFilter();
}
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
访问http://localhost:5555/api-a/hello?accessToken=token返回hello world,访问http://localhost:5555/api-a/hello返回401错误
注意细节
- 简化path与serviceId组合
zuul.rotes.=.
eg:zuul.routes.feign-consumer=/feign-consumer/** - zuul默认为每一个服务实例使用其服务名自动创建映射关系进行路由
例如不配置路由的情况下,访问http://localhost:5555/eureka-client/hello?accessToken=token,可以返回hello world - 使用zuul.ignored-services=/user-service/**,可以跳过该服务,不创建改服务的路由
例如:zuul.ignored-services=*,对所有服务不自动创建路由
自定义路由映射规则
eg: 想要将名称userService-v1的服务映射为/v1/userService/的路由
在主类中加入自定义规则
@Bean
public PatternServiceRouteMapper serviceRouteMapper()
{
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}"
);
}
当匹配表达式的时候,使用此映射规则;不匹配时,采用默认的映射规则
路径匹配
Ant风格
?:匹配任意单个字符
*:匹配任意数量的字符
**:匹配任意数量的字符,支持多级目录
匹配的顺序
路由的规则是通过LinkedHashMap保存的,是有序依次加入的,所以是按照配置的先后顺序匹配的。但是properties文件是无序的,如果要想按照先后顺序匹配,可以使用YAML配置文件
忽略表达式
使用zuul.ignored-patterns可以忽略掉API网关对路由的限制,eg:
zuul.ignored-patterns=/**/hello/**
表示任何访问//hello/的路由都不会得到映射,得不到返回内容
路由前缀
zuul.prefix=/api
Cookie与头信息
在请求路由时,zuul会默认过滤掉HTTP请求头信息中的一些敏感信息,防止他们被传递到下游的外部服务器。默认的敏感头信息通过zuul.sensitiveHeaders参数定义,
包括Cookie、Set-Cookie、Authorization三个属性
- 全局为空覆盖默认值,不推荐
zuul.sensitiveHeaders=
- 指定路由参数配置,推荐
#方法1:对指定路由开启自定义敏感头
zuul.routes.<router>.customSensitiveHeaders=true
#方法2:将指定路由的敏感头设置为空
zuul.routes.<router>.sensitiveHeaders=
重定向的问题
从访问的路由可以看出,访问成功后,http的url仍然是路由跳转前的web应用实例地址,而不是路由的地址,此问题导致spring security和shiro在登陆完成后,请求头信息中的状态码为302,请求响应头信息中的Location指向了具体的服务实例地址,而请求中的host信息缺指向了路由前的host。故网管进行路由转发前的Host信息没有设置正确。
解决方法:
zuul.addHostHeader=true
此解决方案适版本而定
Hystrix和Ribbon支持
Zuul天生拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡功能。但是使用path与url的映射的路由转发不会采用HystrixCommand来包装,不具备线程隔离和断路器的保护功能,也不具备负载均衡的能力
参数配置
- API网关路由转发请求的HystrixCommand执行超时时间的设置,单位为毫秒
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
- 设置路由请求转发,创建请求连接的超时时间
ribbon.ConnectTimeout=2000
当此超时时间小于上面的超时时间时,会自动进行重试路由请求
当大于时,不会断路重连
- 建立连接后的转发请求时间
ribbon.ReadTimeout=3000
短路重连规则同上
- 关闭重试机制
#全局关闭
zuul.retryable=false
#指定路由关闭
zuul.routes.<route>.retryable=false
Spring cloud学习--Zuul01的更多相关文章
- spring cloud 学习(9) - turbine stream无法在eureka注册的解决办法
turbine是啥就不多解释了,初次接触的可以移步spring cloud 学习(4) - hystrix 服务熔断处理 拉到最后看一下,turbine stream默认情况下启动成功后,eureka ...
- Spring Cloud学习(一):Eureka服务注册与发现
1.Eureka是什么 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的. Eureka ...
- spring cloud 学习资料
spring cloud 学习资料 网址 拜托!面试请不要再问我Spring Cloud底层原理 https://mp.weixin.qq.com/s/ZH-3JK90mhnJPfdsYH2yDA
- Spring Boot和Spring Cloud学习资源推荐
Spring Boot和Spring Cloud学习资源推荐 比较好的学习资源,分享一下. 1.Spring Boot官方文档:http://projects.spring.io/spring-b ...
- Spring Cloud 学习 之 Spring Cloud Eureka(源码分析)
Spring Cloud 学习 之 Spring Cloud Eureka(源码分析) Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 ...
- 推荐几个Spring Cloud学习资料
研究Spring Cloud也有一段时间了,手头上有一点收集的资料,分享给小伙伴们学习. 博客 1.跟我学Spring Cloud 2.周立|Spring Cloud 3.Spring Cloud基础 ...
- .net core+Spring Cloud学习之路 二
前言: 原本计划这次写一下搭建eureka群集.但是发现上次写的只是服务的注册,忘了写服务的发现,所以这次先把服务发现补上去. 我们基于上篇文章,再新建两个.net core web api项目,分别 ...
- .net core+Spring Cloud学习之路 一
文章开头唠叨两句. 2019年了,而自己参加工作也两年有余了,用一个词来概括这两年多的生活,就是:“碌碌无为”. 也不能说一点收获都没有,但是很少.2019来了,我立志要打破现状,改变自己,突破自我. ...
- spring cloud学习填坑笔记
最近在学习spring cloud,由于学习资料具有普遍性,部分应个人原因导致的小细节问题,往往很难找到解决的办法.这特别记录一下自己遇到的一些问题. 一.eureka-server加入securit ...
随机推荐
- 【focus-lei 】微服务
随笔分类 - 微服务 .net core使用NLog+Elasticsearch记录日志 摘要:在微服务或分布式系统中,如果将日志作为文件输出,查看系统日志将非常不便:如果将日志保存到数据库中,又不能 ...
- org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [dx.service.ItemService] found for dependency
在整合ssm框架,测试service层的时候报错 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: ...
- 时间戳位数不够13位,通过es6 的padEed补零
if(val.toString().length == 10){ val = val.toString().padEnd(13,"0")*1 //不够十三位放后面补零,超过13位也 ...
- HTML文档流和脱离文档流
文档流:也就是我们通常看到的由左到右.由上而下的元素排列形式,在网页中每个元素都是默认按照这个顺序进行排序和显示的. 脱离文档流:元素脱离文档流之后,将不再在文档流中占据空间,而是处于浮动状态(可以理 ...
- 04.Linux-CentOS系统sudo权限配置
visudo权限配置普通用户的使用权限范围配置文件: (请根据自己公司需求配置) [root@localhost ~]# visudo ## Allow root to run any command ...
- windows重装系统之前与之后进行的操作
1.原系统的备份 避免重装遇到故障无法恢复,给自己留一条后路. 重装系统之前首先进行一次系统备份,我使用的备份软件是dism++,这个软件还可以完成其他的诸如空间回收.系统优化等操作: 软件地址:ht ...
- (NOIP)CSP-S 2019前计划
前言 无 1.NOIP原题板刷 NOIP原题板刷 这是一篇咕了的blog 2.牛客 & ACwing & 洛谷 网课学习 收获还是蛮大的,不过我没有写博客 3.codeforces专项 ...
- CSS3 结构性伪类选择器(2)
CSS3 结构性伪类选择器—first-child “:first-child”选择器表示的是选择父元素的第一个子元素的元素E.简单点理解就是选择元素中的第一个子元素,记住是子元素,而不是后代元素. ...
- css3 动画 Transition
CSS Transition 1.1 基本用法 在CSS 3引入Transition(过渡)这个概念之前,CSS是没有时间轴的.也就是说,所有的状态变化,都是即时完成. 上面是一个演示,当鼠标放置 ...
- 未来HTML5的发展前景如何?黑客专家是这样回答的
如果你想进军IT行业,如果你准备好掌握一项新技术,那么就选择HTML5.近日,我们采访了国内知名网络黑客安全专家郭盛华,帮助您了解当今最重要的技术.在本篇文章中,黑客安全专家郭盛华回答了有关HTML5 ...