17、其它配置

90 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

17、其它配置

二、其它配置

1、请求头配置

在集群的服务间共享请求头并没有什么问题,但是如果请求会被转发到其他系统,那么对于敏感的请求头信息,就需要进行处理。在默认情况下, HTTP 请求头的 Cookie、Set-Cookie、 Authorization 属性不会传递到“源服务”,可以使用 sensitiveHeaders 属性来配置敏感请求头,下面的配置对全局生效:

除了使 sensitiveHeaders 属性外, 还可以使用 ignoredHeaders 属性来配置全局忽略的请求头。使用该配置项后,请求与响应中所配置的头信息均被忽略:

##默认情况下,敏感的头信息无法经过API网关进行传递,我们可以通过如下配置使之可以传递:
#配置请求头  -- 全局配置
zuul.sensitive-headers=accept-language,cookie
#配置请求头  -- 只对一个路由生效
#配置 ribbon 路由规则
zuul.routes.sale.path=/sale/**
zuul.routes.sale.service-id=invoker-server
zuul.routes.sale.sensitive-headers=cookie
#配置全局忽略的请求头   -- 全局配置
zuul.ignored-headers=accept-language

2、路由端点

在网关项目中提供了一个 /routes 服务,可以让我们查看路由映射信息。如果想开启该 服务需要满足以下条件:

  • 网关项目中引入了 Spring Boot Actuator。
  • 项目中使用了@EnableZuulProxy 注解。

一般情况下 Actuator 开启了端点的安全认证,即使符合以上两个条件,也无法访问routes 服务。要解决该问题,可以在配置文件中将 management.security. enabled 属性值设置 为false 关闭安全认证。

以上面介绍的项目为例,开启 /routes 服务后访问 http://localhost:8080/routes,浏览 器中将输出下面 JSON (以下 JSON 经过格式化)

项目需要加入依赖,并修改配置文件:

#配置路由端点,查看路由的映射信息,需要关闭安全验证 -- 访问:http://localhost:8080/routes
management.security.enabled=false
<!-- 健康检查依赖此模块 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
{
    "/books/**": "http://localhost:8888",
    "/eureka-server/**": "eureka-server",
    "/invoker-server/**": "invoker-server",
    "/provider-server/**": "provider-server",
    "/routeTest/163": "http://www.163.com",
    "/routeTest163/**": "http://www.163.com",
    "/sale/**": "invoker-server",
    "/test/**": "forward:/source/hello"
}

3、Zuul与Hystrix

当我们对网关进行配置让其调用集群的服务时,将会执行 Ribbon 路由过滤器(RibbonRoutingFilter )。该过滤器在进行转发时会封装为一个 Hystrix 命令予以执行。换言之,它具有容错的功能。如果“源服务”出现问题(例如超时),那么所执行的 Hystrix 命令将会触发回退,下面将测试 Zuul 中的 回退。 为模块 invoker-server )的控制器添加一个超时方法,请见代码清单 7-7

@GetMapping("/errorHello")
@ResponseBody
public String errorHello() throws InterruptedException {
    Thread.sleep(10000);
    return "Hello World";
}

在网关项目( zuul-gateway )中建立一个网关处理类,处理回退逻辑, 请见代码清单:

public class MyFallbackProvider implements ZuulFallbackProvider {
    @Override
    public String getRoute() {
        return "invoker-server";
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "OK";
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("fallback".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.TEXT_PLAIN);
                return headers;
            }
        };
    }
}

回退处理类需要实现 ZuulFallb ackProvider 接口,实现的 getRoute 方法返回路由的名称, 该方法将与配置中的路由进行对应,本例配置的路由如下:

#配置 ribbon 路由规则
zuul.routes.sale.path=/sale/**
zuul.routes.sale.service-id=invoker-server

简单点说就是,invoker-server 路由出现问题导致触发回退时,由 MyFallbackProvider处理。 MyFallbackProvider 类实现的 fallbackResponse 方法要返回 ClientHttpResponse 实例。本例中返回的 ClientHttpResponse ,内容为 fallback ,也就是回退触发时,调用的客户端将得到 fallback 字符串。 为了让 Spring 容器知道 MyFallbackProvider ,在配置类中新建 MyFallbackProvider 的Bean ,如代码清单 7-9 所示

@Bean
public ZuulFallbackProvider saleFallbackProvider(){
    return new MyFallbackProvider();
}

启动整个集群,在浏览器中访问以下地址 http://localhost:8080/sale/errorHello ,浏览器返回fallback 字符串,可见回退被触发。 以上实现的 MyFallbackProvider 仅对 invoker-server 路由有效,如果相对全局有效,可以使用以下实现。

@Override
public String getRoute() {
    return "invoker-server";
}
上面修改为 下面,既是全局有效

@Override
public String getRoute() {
    return "*";
}

4、在Zuul中预加载Ribbon

调用集群服务时,会使用 Ribbon 的客户端 默认情况下,客户端相关的 ean 会延迟 加载,在 次调用集群服务时,才会初始化这些对象。在第 次调用时,控制台会有以 下的输出 日志(仅截取部分):

image.png

如果想提前加载 Ribbon 客户端,可以在配置文件中进行 以下配置:

# 在Zuul中预加载Ribbon客户端,默认第一次调用集群服务时加载
zuul.ribbon.eager-load.enabled=true

以上的配置在 Spring 容器初始化时,就会创建 Ribbon 客户端的相关实例 启动网关项目可以看到以上的输出日志。 至此, Zuul 的基本功能己经介绍完毕。掌握了前面章节介绍的内容,基本上就可以使用Zuul 了。 接下来,再进一层 ,让我们更深入地学习 Zuul