微服务网关zuul使用指南

逃离我推掉我的手 2022-03-16 08:40 477阅读 0赞

转载自:https://mp.weixin.qq.com/s/yOChVzBMwXIHHQHjKGzI0g

Zuul

简介

Zuul包含了对请求的路由和过滤两个主要的功能,其中路由功能负责将外部的请求转发到具体的微服务实例上,是实现外部访问统一入口的基础上,而过滤功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。

Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获取其他微服务的信息,也即以后访问微服务都是通过Zuul跳转后获得。

代理+路由+过滤三大功能。

使用

需要和Eureka客户端结合使用,依赖如下:

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  4. </dependency>
  5. <!--zuul的依赖-->
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  9. </dependency>

添加配置,将其注册到eureka中,如下:

  1. server:
  2. port: 9001
  3. eureka:
  4. client:
  5. serviceUrl:
  6. defaultZone: http://localhost:7001/eureka # eureka的暴露地址,直接注册
  7. instance:
  8. instance-id: zuul.com
  9. prefer-ip-address: true
  10. spring:
  11. application:
  12. name: zuul #应用的名称,在同一个eureka中必须不重复

在主启动类上添加@EnableZuulProxy这个注解,如下:

  1. @SpringBootApplication
  2. @EnableEurekaClient //开启eurkea客户端
  3. @EnableZuulProxy //开启zuul
  4. public class DeptGetWayZuul9001Application {

启动即可,在eureka中看到注册进入即可

之后只需要通过zuul访问其他的微服务提供者即可,比如服务提供者的实例名称为dept-provider,那么通过zuul访问的路径为

  1. http://localhost:9001/dept-provider/dept/1

路由映射规则

代理名称

之前的配置访问的还是需要带上微服务的实例名称,但是我们不想微服务的实例名称暴露,那么此时就需要使用代理名称替代,配置如下:

  • 使用ignored-services忽略真实的服务名称访问,可以同时指定多个,其中服务名称必须和服务配置文件中一样。
  • 在routes下指定多个路由映射规则。

    zuul:

    忽略真实的服务名称实例访问,是一个Set集合,可以指定多个,取消全部使用 “*”即可

    ignored-services:

    • order-provider

    routes下面指定代理规则,可以同时指定多个

    routes:

    指定第一个规则,这里的名称任意

    api-order:

    指定的实例名称

    1. serviceId: order-provider

    指定可以访问的路由

    1. path: /api-order/**

按照上面的配置完成之后就可以直接使用映射的路由访问即可,如:

  1. http://zuul.com:9001/api-order/order/1

设置统一前缀

我们可以在所有的访问uri前面加上统一的前缀,配置如下:

使用zuul.prefix加上统一的前缀即可

  1. zuul:
  2. #加上统一的前缀,那么访问的时候一定要加上这个前缀才可以访问到
  3. prefix: /chenjiabing
  4. # 忽略真实的服务名称实例访问,是一个Set集合,可以指定多个,取消全部使用 "*"即可
  5. ignored-services:
  6. - order-provider
  7. #routes下面指定代理规则,可以同时指定多个
  8. routes:
  9. #指定第一个规则,这里的名称任意
  10. api-dept:
  11. #指定的实例名称
  12. serviceId: order-provider
  13. #指定可以访问的路由
  14. path: /api-order/**

![wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==][wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw]

通过上面的配置,此时的访问路径变成

  1. http://zuul.com:9001/chenjiabing/api-order/order/1

![wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==][wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw]

某个uri取消路由

使用zuul.ignored-services是忽略一个或者多个微服务的全部接口,但是如果我们可以更细化

如果我们需要隐藏一些敏感的接口不给访问,我们可以在yml文件中配置,如下:

  1. zuul:
  2. ignored-patterns:
  3. - /api-order/order/list # 取消指定的一个
  4. - /api-order/order/** # 使用通配符去掉order下的全部接口

传递敏感头信息

默认zuul是不能传递头信息的,比如cookie,默认的设置了三个字段,如下:

  1. private Set<String> sensitiveHeaders = new LinkedHashSet<>(
  2. Arrays.asList("Cookie", "Set-Cookie", "Authorization"));

如果我们想让它不过滤,只需要将其设置为空,或者不配置其他的,如下:

  • sensitive-headers这个值设置为空即可
  • 这个配置只是针对order-provider这个微服务起作用

    zuul:
    routes:

    指定第一个规则,这里的名称任意

    1. api-order:

    指定的实例名称

    1. serviceId: order-provider

    指定可以访问的路由

    1. path: /api-order/**
    2. sensitive-headers: # 设置为空即可,那么就可以传递敏感头信息了

上面的配置是针对单个服务的设置,我们也可以配置针对所有的服务,如下:

  1. zuul:
  2. sensitive-headers: # 设置所有的服务都取消敏感头信息

过滤器

生命周期

Filter 的生命周期有 4 个,分别是 “PRE”、“ROUTING”、“POST” 和“ERROR”,整个生命周期可以用下图来表示

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5NzIxNDE5_size_16_color_FFFFFF_t_70

生命周期解释如下:

  • PRE这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、鉴权、限流、参数校验、请求转发,在集群中选择请求的微服务、记录调试信息等。
  • ROUTING这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用 Apache HttpClient 或 Netfilx Ribbon 请求微服务。
  • POST这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
  • ERROR在其他阶段发生错误时执行该过滤器。 除了默认的过滤器类型,Zuul 还允许我们创建自定义的过滤器类型。例如,我们可以定制一种 STATIC 类型的过滤器,直接在 Zuul 中生成响应,而不将请求转发到后端的微服务。

前置过滤器的使用

利用前置过滤器实现检测token是否正确,如果不正确,那么直接返回权限不足401状态码,不路由微服务。

继承ZuulFilter。

注入到ioc容器中。

  1. /**
  2. * 自定义过滤器,用于实现鉴权,前置过滤器
  3. * 继承ZuulFilter
  4. */
  5. @Component //一定要注入到ioc容器中
  6. public class TokenFilter extends ZuulFilter {
  7. /**
  8. * 判断过滤器是否被执行,返回true表示被会被执
  9. * 在这里我们可以限制过滤器的执行范围,可以根据指定的条件判断这个请求是否被过滤
  10. */
  11. @Override
  12. public boolean shouldFilter() {
  13. return true;
  14. }
  15. /**
  16. * 过滤器的具体实现逻辑
  17. * @return
  18. * @throws ZuulException
  19. */
  20. @Override
  21. public Object run() throws ZuulException {
  22. RequestContext requestContext = RequestContext.getCurrentContext(); //获取请求上下文
  23. HttpServletRequest request = requestContext.getRequest(); //获取HttpServletRequest
  24. String token = request.getParameter("token"); //获取传递过来的请求参数
  25. //如果token是空的,返回权限不足,一般返回的状态码是401
  26. if (StringUtils.isEmpty(token)) {
  27. requestContext.setSendZuulResponse(false); //设置false,此时的zuul不对此路由
  28. requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); //设置401
  29. // requestContext.setResponseBody("no power"); //设置响应的消息
  30. }
  31. return null;
  32. }
  33. /**
  34. * 指定过滤器的类型,前置,后置.................
  35. * 1、其中FilterConstants这个常量类中定义了过滤器常用的变量
  36. * public static final String ERROR_TYPE = "error";
  37. public static final String POST_TYPE = "post";
  38. public static final String PRE_TYPE = "pre";
  39. public static final String ROUTE_TYPE = "route";
  40. * @return
  41. */
  42. @Override
  43. public String filterType() {
  44. return FilterConstants.PRE_TYPE; //前置过滤器 pre
  45. }
  46. /**
  47. * 过滤器执行的顺序,数字越小优先级越高
  48. * @return
  49. */
  50. @Override
  51. public int filterOrder() {
  52. //一般前置过滤器放在org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter这个过滤器之前即可,只需要将其对应的顺序-1
  53. return FilterConstants.PRE_DECORATION_FILTER_ORDER-1;
  54. }
  55. }

后置过滤器的使用

利用后置过滤器在响应头中添加内容,和前置过滤器的使用一样,只是使用的过滤器的类型不用,如下:

  1. /**
  2. * 后置过滤器,在响应头中添加一些内容
  3. */
  4. @Component //注入
  5. public class AddResponseHeaderFilter extends ZuulFilter {
  6. @Override
  7. public boolean shouldFilter() {
  8. return true;
  9. }
  10. @Override
  11. public Object run() throws ZuulException {
  12. RequestContext requestContext = RequestContext.getCurrentContext(); //获取请求上下文
  13. HttpServletResponse response = requestContext.getResponse(); //获取HttpServletResponse
  14. response.addHeader("X-Foo", "add header"); //添加头信息
  15. return null;
  16. }
  17. @Override
  18. public String filterType() {
  19. return FilterConstants.POST_TYPE; //后置过滤器
  20. }
  21. @Override
  22. public int filterOrder() {
  23. //在org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#filterOrder()这个过滤一起之前执行即可
  24. return FilterConstants.SEND_RESPONSE_FILTER_ORDER-1;
  25. }
  26. }

禁用某种过滤器

如果我们想要禁用某种过滤器(自定义或者zuul自身的),我们可以在配置中设置,格式:zuul.<SimpleClassName>.<filterType>.disable=true,比如禁用我们TokenFilter,如下:

  1. zuul:
  2. TokenFilter: # 类的名字
  3. pre: # 类型
  4. disable: true

限流

令牌桶算法

https://blog.csdn.net/tianyaleixiaowu/article/details/74942405

https://baike.baidu.com/item/%E4%BB%A4%E7%89%8C%E6%A1%B6%E7%AE%97%E6%B3%95/6597000?fr=aladdin

系统按照恒定的速率往指定大小的桶里添加令牌,每来一个请求就消耗一个令牌,如果桶内没有令牌表示此事的请求流量已经超过设置的大小了,应该做出相应的响应或者直接抛出异常

实现

使用前置过滤器,在请求被转发之前调用,限流的过滤器应该是所有过滤器中优先级最大的

使用google开源的组件Guava

  1. import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
  2. import org.springframework.http.HttpStatus;
  3. import org.springframework.stereotype.Component;
  4. import com.google.common.util.concurrent.RateLimiter;
  5. import com.netflix.zuul.ZuulFilter;
  6. import com.netflix.zuul.context.RequestContext;
  7. import com.netflix.zuul.exception.ZuulException;
  8. /**
  9. * 限流 ,前置过滤器
  10. * 限流的过滤器的优先级应该是最高,数字最小
  11. */
  12. @Component
  13. public class RateFilter extends ZuulFilter {
  14. private static final RateLimiter RATE_LIMITER=RateLimiter.create(100); //程每秒钟往桶里放置100个令牌
  15. @Override
  16. public boolean shouldFilter() {
  17. return true;
  18. }
  19. @Override
  20. public Object run() throws ZuulException {
  21. /**
  22. * tryAcquire():如果获取不到一个令牌,表示流量超时了,没有等待时间
  23. * tryAcquire(int permits, long timeout, TimeUnit unit):获取permits个令牌,如果在指定的时间timeout内,还是没有获取到指定的permits个令牌,那么就返回false
  24. */
  25. if (!RATE_LIMITER.tryAcquire()) {
  26. RequestContext requestContext = RequestContext.getCurrentContext();
  27. requestContext.setSendZuulResponse(false); //不路由
  28. requestContext.setResponseStatusCode(HttpStatus.FORBIDDEN.value()); //403拒绝访问
  29. }
  30. //也可以直接抛出异常
  31. // if (!RATE_LIMITER.tryAcquire()) {
  32. // throw new RuntimeException(); //抛出异常
  33. // }
  34. return null;
  35. }
  36. @Override
  37. public String filterType() {
  38. return FilterConstants.PRE_TYPE; //前置
  39. }
  40. @Override
  41. public int filterOrder() {
  42. //org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter#filterOrder()这个过滤器的优先级是最高的,只需要-1即可
  43. return FilterConstants.SERVLET_DETECTION_FILTER_ORDER-1;
  44. }
  45. }

多维度限流

https://segmentfault.com/a/1190000012252677

鉴权

https://www.jianshu.com/p/f89f5557990f

一些api只有具有某些权限的时候才可以被调用,比如用户的一些相关信息,只有在用户登录之后才可以调用,否则将会提示没有权限

实现

我们在用户登录成功之后会在返回头中添加cookie的值为openId=random(随机数),并且将其保存在redis中(key=openId_userId,value=random)

  1. /**
  2. * 登录的方法,登录成功响应头返回添加cookie
  3. * @param response
  4. * @return
  5. */
  6. @GetMapping("/user/login")
  7. public String login(HttpServletResponse response) {
  8. //登录的逻辑。。。。。
  9. //设置cookie的值
  10. Cookie cookie=new Cookie("openId", UUID.randomUUID().toString());
  11. cookie.setMaxAge(60*60);
  12. response.addCookie(cookie); //添加到响应头中
  13. //添加到redis中,key=openId_userId,value=uuid的值
  14. return "登录成功";
  15. }

我们事先将指定权限的接口uri存放在数据库中,在zuul中定义一个鉴权的过滤器,如果请求过来了,判断这个uri是否需要某种权限才能调用,如果不需要直接路由即可,如果需要那么判断cookie中是否有openId,如果没有表示没有登录,权限不够,如果有,需要判断和redis中的值是否相同,如果相同,表示有权限,直接路由到服务即可。

这里将部分逻辑写在shouldFilter()方法中,限制范围(判断请求的uri是否需要鉴权),run()方法中只需要判断是否具有权限即可。

  1. /**
  2. * 自定义过滤器,用于实现鉴权,前置过滤器
  3. * 继承ZuulFilter
  4. */
  5. @Component //一定要注入到ioc容器中
  6. public class TokenFilter extends ZuulFilter {
  7. @Resource
  8. private UriService uriservice; //注入
  9. @Resource
  10. private RedisTemplate redisTemplate; //redis
  11. /**
  12. * 判断过滤器是否被执行,返回true表示被会被执行(经过run方法)
  13. * 只需要判断请求的uri是存在数据库中即可
  14. */
  15. @Override
  16. public boolean shouldFilter() {
  17. RequestContext context=RequestContext.getCurrentContext(); //获取上下文
  18. HttpServletRequest request = context.getRequest(); //获取request
  19. String uri=request.getRequestURI(); //获取请求的uri
  20. /**
  21. * 伪代码如下:
  22. * 1、List<URL> uriList=uriservice.getUrlList(); //获取需要权限访问的uri列表
  23. * 2、判断请求的uri是否在uriList中
  24. * 1、如果不存在,return false,表示不用执行过滤的逻辑(run方法)直接路由到指定的服务即可
  25. * 2、如果不存在返回true,表示执行过滤的逻辑(run方法)
  26. */
  27. return true;
  28. }
  29. /**
  30. * 过滤器的具体实现逻辑,经过shouldFilter方法之后,能够执行到这里的表示这个请求的uri需要验证权限
  31. * @return
  32. * @throws ZuulException
  33. */
  34. @Override
  35. public Object run() throws ZuulException {
  36. RequestContext requestContext = RequestContext.getCurrentContext(); //获取请求上下文
  37. HttpServletRequest request = requestContext.getRequest(); //获取HttpServletRequest
  38. Cookie[] cookies = request.getCookies(); //获取cookie
  39. /**
  40. * 伪代码如下:
  41. * 1、判断cookie中是否存在openId
  42. * 1、如果不存在,返回权限不足的提示信息
  43. * 2、如果存在,需要判断redis中存储的openId的值是否和携带过来的cookie值相同
  44. * 1、如果不相同,返回权限不足的提示信息
  45. * 2、如果相同,表示这个请求具有相应的权限
  46. */
  47. return null;
  48. }
  49. @Override
  50. public String filterType() {
  51. return FilterConstants.PRE_TYPE; //前置过滤器 pre
  52. }
  53. @Override
  54. public int filterOrder() {
  55. //一般前置过滤器放在org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter这个过滤器之前即可,只需要将其对应的顺序-1
  56. return FilterConstants.PRE_DECORATION_FILTER_ORDER-1;
  57. }
  58. }

跨域

  1. import java.util.Arrays;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.cors.CorsConfiguration;
  5. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  6. import org.springframework.web.filter.CorsFilter;
  7. /**
  8. * 跨域的配置类
  9. */
  10. @Configuration //配置类
  11. public class CorsConfig {
  12. @Bean
  13. public CorsFilter corsFilter() {
  14. final UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
  15. final CorsConfiguration config=new CorsConfiguration();
  16. config.setAllowCredentials(true); //支持cookie跨域
  17. config.setAllowedOrigins(Arrays.asList("*")); //配置允许跨域访问的域名,这里*表示全部
  18. config.setAllowedHeaders(Arrays.asList("*")); //设置允许的头
  19. config.setAllowedMethods(Arrays.asList("*")); //设置允许跨域的方法,GET,POST....,这里表示允许全部
  20. config.setMaxAge(300l); //缓存时间,在指定的时间内,对于相同的请求就不需要再次检查了
  21. source.registerCorsConfiguration("/**", config);
  22. return new CorsFilter(source);
  23. }
  24. }

超时时间设置

我们在使用zuul访问服务的时候,一旦服务超过很短的时间没有响应,那么zuul就会自动熔断,默认的时间是2秒,但是可以通过配置修改,如下:由于zuul使用ribbon实现负载均衡,因此这里还需要配置ribbon的超时时间,否则配置将不会生效

  1. zuul:
  2. host: # 配置zuul的超时时间
  3. connect-timeout-millis: 60000 # 默认2秒,
  4. socket-timeout-millis: 60000
  5. ribbon: # zuul使用服务发现的时候,要想让上面的配置生效,必须配置ribbon的超时时间
  6. ReadTimeout: 60000 # 请求处理时间。
  7. ConnectTimeout: 60000 # 请求连接时间。

服务熔断

当请求的服务响应时间超时或者服务不可用的时候zuul会直接响应异常,我们可以设置熔断,只需要在zuul的服务中配置即可,如下:

  1. package cn.tedu.zuul.hystrix;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
  6. import org.springframework.http.HttpHeaders;
  7. import org.springframework.http.HttpStatus;
  8. import org.springframework.http.MediaType;
  9. import org.springframework.http.client.ClientHttpResponse;
  10. import org.springframework.stereotype.Component;
  11. /**
  12. * 设置zuul的熔断
  13. * 实现FallbackProvider接口
  14. * 出现熔断的情况如下:
  15. * 1、当请求的服务响应超时
  16. * 2、当请求的服务不能正常提供服务
  17. */
  18. @Component //注入到IOC容器
  19. public class OrderFallback implements FallbackProvider {
  20. /**
  21. * 这个方法返回的是serviceId,如果返回的单个服务,那么只针对一个服务熔断
  22. * 如果想要针对所有的服务进行配置熔断,只需要返回*即可
  23. */
  24. @Override
  25. public String getRoute() {
  26. return "order-provider";
  27. }
  28. /**
  29. * 发生熔断的响应方法
  30. */
  31. @Override
  32. public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
  33. return new ClientHttpResponse() {
  34. @Override
  35. public HttpStatus getStatusCode() throws IOException {
  36. return HttpStatus.OK;
  37. }
  38. @Override
  39. public int getRawStatusCode() throws IOException {
  40. return 200;
  41. }
  42. @Override
  43. public String getStatusText() throws IOException {
  44. return "OK";
  45. }
  46. @Override
  47. public void close() {
  48. }
  49. //设置响应的内容
  50. @Override
  51. public InputStream getBody() throws IOException {
  52. return new ByteArrayInputStream("fallback".getBytes());
  53. }
  54. @Override
  55. public HttpHeaders getHeaders() {
  56. HttpHeaders headers = new HttpHeaders();
  57. headers.setContentType(MediaType.APPLICATION_JSON);
  58. return headers;
  59. }
  60. };
  61. }
  62. }

zuul的重试

有时候因为网络或者其它原因,服务可能会暂时的不可用,这个时候我们希望可以再次对服务进行重试,Zuul也帮我们实现了此功能,需要结合Spring Retry 一起来实现

依赖:

  1. <!-- 超时重试 -->
  2. <dependency>
  3. <groupId>org.springframework.retry</groupId>
  4. <artifactId>spring-retry</artifactId>
  5. </dependency>

在配置文件中配置如下:

  • 在zuul中开启重试机制
  • 配置ribbon的重试次数
  • 默认请求超时时间很短,还可以配置ribbon的超时时间

    zuul:
    retryable: true # 开启重试机制
    ribbon: # zuul内部使用的是ribbon实现负载均衡的,因此配置ribbon的重试次数
    MaxAutoRetries: 2 # 同一个服务的最大重试次数
    MaxAutoRetriesNextServer: 2 # 对于切换的下一个实例的重试次数

Zuul的高可用

将多个zuul的微服务注册到Eureka中的(集群)

Nginx和Zuul混搭的方式,可以将Nginx的请求转发到多个zuul中,zuul再路由给指定的微服务

完整的配置

  1. zuul:
  2. # TokenFilter:
  3. # pre:
  4. # disable: true
  5. # 忽略真实的服务名称实例访问,是一个Set集合,可以指定多个,取消全部使用 "*"即可
  6. sensitive-headers: # 设置所有的服务都取消敏感头信息
  7. ignored-services:
  8. - order-provider
  9. # ignored-patterns:
  10. # - /api-order/order/list # 取消指定的一个
  11. # - /api-order/order/** # 使用通配符去掉order下的全部接口
  12. #routes下面指定代理规则,可以同时指定多个
  13. routes:
  14. #指定第一个规则,这里的名称任意
  15. api-order:
  16. #指定的实例名称
  17. serviceId: order-provider
  18. #指定可以访问的路由
  19. path: /api-order/**

消费端的使用

前提:

  • zuul微服务(zuul-server)注册到eureka注册中心
  • 微服务提供者注册到Eureka注册中心,zuul-server配置的路由是api-order
  • 服务消费者注册到Eureka中

那么如果消费者想用通过zuul-server访问到服务提供者,那么可以直接写http://zuul-server/api-order/order/{id}

  1. @RestController
  2. public class OrderController {
  3. private final static String URI_PRFIX="http://zuul-server/api-order"; //直接使用zuul网管连接订单的服务提供者
  4. @Resource
  5. private RestTemplate restTemplate;
  6. @GetMapping("/order/{id}")
  7. public Order getOrder(@PathVariable("id")Integer id) {
  8. return restTemplate.getForObject(URI_PRFIX+"/order/"+id, Order.class);
  9. }
  10. }

源码

https://gitee.com/chenjiabing666/zuul-server.git

参考文章

https://windmt.com/2018/04/23/spring-cloud-11-zuul-filter/

https://cloud.spring.io/spring-cloud-netflix/2.0.x/single/spring-cloud-netflix.html\#\_router\_and\_filter\_zuul

https://mp.weixin.qq.com/s/FsvZgkvpI0S6rposacGiiQ

[wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw]:

发表评论

表情:
评论列表 (有 0 条评论,477人围观)

还没有评论,来说两句吧...

相关阅读

    相关 服务网netflix-zuul

    1. 网关介绍 当使用单体应用程序架构时,客户端(web和移动端)通过向后端应用程序发起一次REST调用来获取数据。负载均衡器将请求路由给N个相同的应用程序实例中的一个。

    相关 服务网zuul

    微服务网关 在微服务环境下,不同的服务有其不同的网络地址,若让客户端直接与各个微服务通信,客户端会多次请求不同微服务,存在跨域请求,处理相对复杂。此时我们就需要使用微服务网关