spring cloud zuul实践

打印 上一主题 下一主题

主题 881|帖子 881|积分 2643

一、 描述
Spring Cloud Zuul是基于Netflix开源的Zuul项目构建而成,它作为微服务架构中的网关服务,主要用于实现动态路由、负载均衡和请求过滤等功能。

  • 动态路由:Zuul根据预设的路由规则将进来的请求路由到相应的服务实例上。路由规则可以通过配置文件或代码进行定义,接收到请求后,Zuul会解析请求的URL,并根据配置的路由规则找到对应的服务地址,将请求转发到目标服务。
  • 负载均衡:Zuul内置了Ribbon负载均衡器,可以对请求进行负载均衡。当一个服务有多个实例时,Zuul可以使用负载均衡算法将请求均匀地分发到不同的实例上,以提高系统的性能和可扩展性。
  • 请求过滤:Zuul支持自定义过滤器,在请求被路由之前或之后对请求进行处理。过滤器可以用于在路由前进行身份验证、请求统计、参数校验等操作,也可以在路由后处理响应结果,比如修改返回数据、添加自定义的响应头等。开发者可以根据需求创建不同类型的过滤器,并定义过滤器的执行顺序。
  • 整合服务注册中心:Zuul可以与服务注册中心(如Zookeeper、Eureka)进行整合,实现动态路由和负载均衡。通过与服务注册中心交互,Zuul能够动态地获取服务实例的信息,并根据需要进行路由和负载均衡。
  • 高可用和容错:Zuul支持配置多个实例运行在不同的机器上,以实现高可用性。当一个Zuul实例发生故障时,其他实例可以接管请求处理,确保系统的稳定性和容错性。
Spring Cloud Zuul通过动态路由、负载均衡和请求过滤等机制,提供了一个强大且灵活的网关服务。它能够统一管理微服务的入口,实现请求的转发和过滤,简化了微服务架构中的通信和调用方式,提高了系统的可伸缩性和可维护性。
      下面是使用Spring Cloud Zuul的一般实践步骤
二、添加依赖
引入zuul的依赖spring-cloud-starter-netflix-zuul
  1. 1     <dependency>
  2. 2       <groupId>org.springframework.cloud</groupId>
  3. 3       <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  4. 4     </dependency>
复制代码
View Code三、创建启动类:
      创建一个启动类,并使用@EnableZuulProxy注解开启Zuul代理功能。
  1. 1 @SpringBootApplication
  2. 2 @EnableZuulProxy
  3. 3 public class GatewayApplication {
  4. 4
  5. 5   public static void main(String[] args) {
  6. 6     SpringApplication.run(GatewayApplication.class, args);
  7. 7   }
  8. 8
  9. 9 }
复制代码
View Code四、 配置
在配置文件(如application.yml)中定义Zuul的路由规则。可以使用Zuul的zuul.routes前缀来配置不同的路由规则。
  1. 1 server:
  2. 2   port: 9000
  3. 3 management:
  4. 4   endpoints:
  5. 5     web:
  6. 6       exposure:
  7. 7         include: '*'
  8. 8   server:
  9. 9     port: 12345
  10. 10 zuul:
  11. 11   routes:
  12. 12     configserver:
  13. 13       path: /myConfig/**
  14. 14       serviceId: config
  15. 15     user:
  16. 16       path: /myUser/**
  17. 17       serviceId: provider
  18. 18   ignored-patterns: #忽略指定的路由
  19. 19     - /config/**
  20. 20     - /gateway/**
  21. 21   sensitive-headers:
  22. 22 #  ignore-local-service: true # 忽略原来自身的路由。比如,true: 原来的config/xxx/xxx不可再访问
复制代码
View Code上述配置将/myConfig/**的请求转发到config服务,将/myUser/**的请求转发到provider服务。
还可以将网关注册到注册中心实现高可用。创建bootstrap.yml文件
  1. 1 spring:
  2. 2   application:
  3. 3     name: gateway
  4. 4   cloud:
  5. 5     zookeeper:
  6. 6       discovery:
  7. 7         register: true
  8. 8         enabled: true
  9. 9       connect-string: 192.168.3.100:2181
  10. 10     config:
  11. 11       discovery:
  12. 12         service-id: config
  13. 13         enabled: true
复制代码
View Code五、配置过滤器
 通过zuul添加过滤器,对请求进行拦截或校验等等
  1. 1 package com.mike.study.gateway.fiter;
  2. 2
  3. 3 import com.netflix.zuul.ZuulFilter;
  4. 4 import com.netflix.zuul.context.RequestContext;
  5. 5 import com.netflix.zuul.exception.ZuulException;
  6. 6 import org.apache.commons.lang.StringUtils;
  7. 7 import org.springframework.http.HttpStatus;
  8. 8 import org.springframework.stereotype.Component;
  9. 9
  10. 10 import javax.servlet.http.HttpServletRequest;
  11. 11
  12. 12 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
  13. 13 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
  14. 14
  15. 15 /**
  16. 16  * @Classname ParameterFilter
  17. 17  * @Created by Michael
  18. 18  * @Date 2023/7/12
  19. 19  * @Description 自定义过滤器
  20. 20  */
  21. 21 @Component
  22. 22 public class ParameterFilter extends ZuulFilter {
  23. 23   /**
  24. 24    * 前置过滤
  25. 25    * @return
  26. 26    */
  27. 27   @Override
  28. 28   public String filterType() {
  29. 29     return PRE_TYPE;
  30. 30   }
  31. 31
  32. 32   /**
  33. 33    * 数值越小,优先级越高
  34. 34    * @return
  35. 35    */
  36. 36   @Override
  37. 37   public int filterOrder() {
  38. 38     return PRE_DECORATION_FILTER_ORDER - 1;
  39. 39   }
  40. 40
  41. 41   @Override
  42. 42   public boolean shouldFilter() {
  43. 43     return true;
  44. 44   }
  45. 45
  46. 46   @Override
  47. 47   public Object run() throws ZuulException {
  48. 48
  49. 49     // 获取请求对象
  50. 50     RequestContext context = RequestContext.getCurrentContext();
  51. 51     HttpServletRequest request = context.getRequest();
  52. 52     // 获取地址栏传入的参数
  53. 53     String token = request.getParameter("token");
  54. 54     System.out.println("token ===>"+token);
  55. 55     //模拟校验token,没有token则终止转发
  56. 56     if (StringUtils.isEmpty(token)) {
  57. 57       context.setSendZuulResponse(false);
  58. 58       context.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
  59. 59     }
  60. 60     return null;
  61. 61   }
  62. 62 }
复制代码
ParameterFilter.java以上代码时在转发请求服务前,对参数进行校验,如果没有token参数,则停止转发,并且返回401错误
六、测试
测试网关转发主要需要请求发起方,网关和请求处理方。这里在原来demo的基础上,增加网关,所以看到有配置中心,以往的文章有项目的搭建介绍。如果不想那么复杂,可以去掉配置中心,将配置放置各个module即可,项目组如下

 
准备请求发起方,即consumer,controller通过feign框架请求网关,网关转发请求provider。consumer的controller如下
  1. 1 import com.mike.study.orderconsumer.client.UserClient;
  2. 2 import com.mike.study.orderconsumer.vo.UserVo;
  3. 3 import org.springframework.web.bind.annotation.GetMapping;
  4. 4 import org.springframework.web.bind.annotation.PathVariable;
  5. 5 import org.springframework.web.bind.annotation.RequestParam;
  6. 6 import org.springframework.web.bind.annotation.RestController;
  7. 7
  8. 8 import javax.annotation.Resource;
  9. 9
  10. 10 /**
  11. 11  * @Classname UserRuttingController
  12. 12  * @Created by Michael
  13. 13  * @Date 2023/7/9
  14. 14  * @Description feign框架调用provider api
  15. 15  */
  16. 16 @RestController
  17. 17 public class UserRuttingController {
  18. 18   @Resource
  19. 19   private UserClient userClient;
  20. 20
  21. 21   @GetMapping("warp/user/2.1/{id}")
  22. 22   public UserVo getUser(@PathVariable("id") Integer userId, @RequestParam("token") String token) {
  23. 23     System.out.println("使用feign框架调用provide的api");
  24. 24     return userClient.getUser(userId, token);
  25. 25   }
  26. 26 }
复制代码
controllerFeign接口
  1. 1 import com.mike.study.orderconsumer.vo.UserVo;
  2. 2 import org.springframework.cloud.openfeign.FeignClient;
  3. 3 import org.springframework.web.bind.annotation.GetMapping;
  4. 4 import org.springframework.web.bind.annotation.PathVariable;
  5. 5 import org.springframework.web.bind.annotation.RequestParam;
  6. 6
  7. 7 /**
  8. 8  * @Classname UserFeigClient
  9. 9  * @Created by Michael
  10. 10  * @Date 2023/7/9
  11. 11  * @Description feign client
  12. 12  */
  13. 13
  14. 14 @FeignClient("gateway")
  15. 15 public interface UserClient {
  16. 16
  17. 17   @GetMapping("myUser/user/{id}")
  18. 18   public UserVo getUser(@PathVariable("id") Integer userId,@RequestParam("token") String token);
  19. 19 }
复制代码
UserClient 以上Feign接口配合注册中心zookeeper使用,访问的网关地址,而不是直接请求服务提供者的api。
provider module简单提供一个api查询用户信息。
六、测试结果
positive case:token参数有值

 negative case:token参数i为空

 
总结,就是consumer不再直接请求provider server,而是通过zuul作为中转站,这样做的好处很多,比如,对consumer的请求进行拦截过滤,验证,降流等等。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

渣渣兔

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表