SpringCloud 使用Zuul构建API Gateway
2020-02-17 16:05:50来源:博客园 阅读 ()
SpringCloud 使用Zuul构建API Gateway
网关的概念
服务A、B都是暴露出来,供外部直接调用的,
- 有时候需要对请求进行过滤、校验,比如检验用户是否已登陆,可以写在暴露出来的每个服务中,但要在多个服务中写相同的代码,太繁琐,可以提出来,放在网关中。
- 如果A、B进行集群,需要负载均衡来确定使用A|B的哪个节点来处理,可以使用网关来进行路由转发(负载均衡)。
网关相当于服务前面的一道关卡,即服务入口,可以统一进行请求的过滤、校验,可以实现路由。
Ribbon实现服务内部的负载均衡(C、D),网关实现暴露出来的服务的负载均衡(A、B)。
外部不直接访问服务A、B,而是访问网关,通过网关来访问A、B。
如果A、B不集群,网关每次都转发到A|B固定的节点(因为这个服务只有这一个节点),一成不变、是静态的,叫做静态路由。
如果A、B集群,这次可能转发到A|B的某个节点,下次可能转发到A|B的另一个节点,转发的节点不是固定的,是会变化的、动态的,叫做动态路由。
如果网关进行了集群,还需Nginx进行负载均衡,来确定使用哪个网关节点。
Zuul是实现网关的一种技术、一个框架,被SpringCloud集成了。
使用Zuul进行路由转发
(1)新建子模块api-gateway
(2)pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
网关要作为Eureka客户端,因为要从Eureka服务器获取服务节点列表,使用Eureka客户端内置的Ribbon进行负载均衡。
所以Eureka客户端的配置都要有。
(3)引导类
@SpringBootApplication @EnableEurekaClient @EnableZuulProxy //也可以使用@EnableZuulServer public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } }
默认使用的是Ribbon的轮询,如果要使用其它策略,修改方式和Ribbon的完全相同。
(4)application.properties
### gateway config###
#使用的端口
server.port=11001
#提供的服务,服务名称
spring.application.name=api-gateway
#2个配置为一组,可配置多组
#开头是固定的zuul.routes,结尾也是固定的path、service-id,中间部分相当于这组配置的id,可随意取
#映射地址
zuul.routes.user-service.path=/user-server/**
#要映射的服务
zuul.routes.user-service.service-id=user-server
#注册到Eureka服务器
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:9001/eureka/
#本机地址,上线时要改为机器实际的ip
eureka.client.ipAddress=127.0.0.1
#实例名,以ip:port的形式注册到server上
eureka.instance.instance-id=${eureka.client.ipAddress}:${server.port}
#注册节点时IP优先,默认为false——注册主机名
eureka.instance.prefer-ip-address=true
#多久发送一次心跳,默认30s,调试时可设置短些
#eureka.instance.lease-renewal-interval-in-seconds=30
请求地址:http://ip:port/user-server/user/order/{user_id}
使用网关(Zuul)的ip:port,后面跟该服务名映射的path(不是服务名,只不过上面我设置的path和服务名相同)
会自动根据path找到对应的服务名(service_id),负载均衡确定要使用该服务的哪个节点。不同的服务(暴露出来的那些服务)映射到不同的path。
可以添加前缀:
zuul.prefix=/api
请求地址:请求地址:http://ip:port/api/user-server/user/order/{user_id} 加在映射地址前面的
ajax的url、<a>链接的href、<form>的action写上面的请求地址。
以后调用消费者(暴露出来的服务)时,不直接调用,而是使用上面的url,通过网关来调用,
网关相当于一个接口(API),提供网关的地址、服务的path供外部调用,所以网关(gateway)又叫做API gateway。
此处网关并未集群,所以直接使用网关的ip:port,请求发给网关;
如果网关要集群,需要使用Nginx做网关的负载均衡,请求发给Nginx。
使用Zuul对请求进行过滤
新建一个包filter,包下新建一个类MyFilter:
@Component //放到spring容器中即可,会自动使用此拦截器 public class MyFilter extends ZuulFilter { //需要继承ZuulFilter
//指定过滤时机 //String类型,"pre"——路由转发之前,"routing"——路由转发之时,"post"——路由转发之后,"error"——发生错误时 @Override public String filterType() { return "pre"; }
//设置此拦截器的执行顺序 // 因为可能有多个拦截器,设置一个int型的值,数值越小,优先级越高、越先执行 @Override public int filterOrder() { return 0; } //是否要进行过滤,即是否要使用此过滤器,这个需要改一下,因为默认为false @Override public boolean shouldFilter() { return true; } //核心方法,进行过滤 @Override public Object run() { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); //获取传递的参数、验证权限 String token = request.getParameter("token"); //token要和数据库查到的进行比较,此处随便写一个代替 if (token==null || !token.equals("123456")) { //直接就返回响应了,请求终止,不再转发给服务 currentContext.setSendZuulResponse(false); currentContext.setResponseStatusCode(400); //把提示信息显示到页面 try { currentContext.getResponse().getWriter().write("token is invalid"); } catch (IOException e) { e.printStackTrace(); } } return null; }
}
说明
网关的请求过滤会过滤所有对暴露出来的服务的请求,所以一般写通用的过滤,比如登录状态检验,如果不是通用的,要写在服务中。
如果暴露出来的服务没有集群,可以不使用网关,直接请求服务节点即可。
文件上传使用SpringMVC的文件上传,但网关默认对上传文件的大小、请求的大小有限制,需要我们在网关的application.properties中配置一下:
#上传文件的最大尺寸,默认1MB
spring.servlet.multipart.max-file-size=2000MB
#请求的最大尺寸,默认10MB
spring.servlet.multipart.max-request-size=2500MB
在引导类上可以使用@EnableZuulProxy、@EnableZuulServer,这2个注解基本差不多,微小的区别是:
实现过滤器时要继承ZuulFilter类,要指定过滤时机,这个类有很多子类,这些子类已经指定了时机,我们可以直接继承来用,这样就不用指定过滤时机了,使用@EnableZuulServer,少部分子类用不了,影响不大。
不建议使用大量的过滤器,因为会加大时间开销,拉低性能。
原文链接:https://www.cnblogs.com/chy18883701161/p/12323941.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:分布式一致性读书笔记
下一篇:线程池
- 聊聊 OAuth 2.0 的 token expire_in 使用 2020-06-08
- 为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用 2020-06-06
- 学习笔记之方法引用 2020-06-06
- idea使用小技巧(一) 2020-06-05
- 用斗地主的实例学会使用java Collections工具类 2020-06-05
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash