返回 导航

SpringBoot / Cloud

hangge.com

API网关服务组件Spring Cloud Zuul使用详解2(路由详解2:服务路由配置)

作者:hangge | 2020-10-12 08:10

二、面向服务的路由配置

1,准备工作

    传统路由的配置方式需要运维人员花费大量的时间来维护各个路由 path url 的关系。为了解决这个问题,Spring Cloud Zuul 实现了与 Spring Cloud Eureka 的无缝整合,我们可以让路由的 path 不是映射具体的 url ,而是让它映射到某个具体的服务,而具体的 url 则交给 Eureka 的服务发现机制去自动维护。这类的路由便称为面向服务的路由。

(1)为了与 Eureka 整合,我们需要在 api-gateway 项目的 pom.xml 中引入 spring-cloud-starter-netflix-eureka-client 依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

(2)接着编辑项目的 application.properites 文件,指定服务注册中心的地址:
#指定服务注册中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

(3)将服务注册中心、之前构建的 hello-servicefeign-consumer 以及用 Spring Cloud Zuul 构建的 api-gateway 都启动起来,在 eureka-server 信息面板中可以看到如下服务:

2,服务路由的默认规则

(1)当我们为 Spring Cloud Zuul 构建的 API 网关服务引入 Spring Cloud Eureka 之后,它会为 Eureka 中的每个服务都自动创建一个默认路由规则:使用服务名作为 path 请求前缀。

(2)比如 http://192.168.0.118:5555/hello-service/hello 这个请求就会直接转发到 HELLO-SERVICE 服务实例上:
注意:由于 HELLO-SERVICE 有两个实例,那么请求便会轮询转发到 http://192.168.0.118:8081/hello http://192.168.0.118:8082/hello 上。

3,关闭默认规则

(1)虽然这种自动化地映射规则很方便,但会使得一些我们不希望对外开放的服务也可能被外部访问到。这个时候,我们可以使用 zuul.ignored-services 配置需要忽略的微服务(多个微服务通过逗号隔开),这样就不会自动对其创建路由规则:
zuul.ignored-services=hello-service

(2)当然我们也可以使用如下设置,对所有的服务都不自动创建路由规则。
zuul.ignored-services=*

4,手动配置服务路由

(1)如果我们关闭了 Zuul 的自动创建默认路由功能(当然如果没有关闭也不影响手动配置),可以使用 path service-id 映射的配置方式手动设置服务路由。
下面配置的作用:
  • 当发起 http://localhost:5555/api-a/hello 请求时:根据匹配规则,请求会由 api-a 路由否则转发,而该路由映射的 service-idhello-service,那么最终 /hello 请求会被发送到 hello-service 服务的某个实例上去。
  • 当发起 http://localhost:5555/api-b/feign-consumer 请求时:根据匹配规则,请求会由 api-b 路由否则转发,而该路由映射的 service-id feign-consumer,那么最终 /feign-consumer 请求会被发送到 feign-consumer 服务的某个实例上去。
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.service-id=hello-service

zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.service-id=feign-consumer

(2)当然我们还可以使用另外一种更简洁的配置方式:zuul.routes.=
下面配置的效果同上面的是一样的。
zuul.routes.hello-service=/api-a/**
zuul.routes.feign-consumer=/api-b/**

附:自定义服务与路由映射规则

(1)前面介绍过默认情况下,Zuul 自动为服务创建的路由表达式会采用服务名作为前缀。假设我们有如下几个微服务,它们使用 <服务名>-v<数字> 格式命名:
  • userservice-v1
  • userservice-v2
  • orderservice-v1

(2)那么针对上面的微服务,Zuul 会自动产生如下相应的路径表达式来映射:
  • /userservice-v1
  • /userservice-v2
  • /orderservice-v1

(3)如果觉得默认规则不合适的话,我们可以使用 Zuul 中自定服务与路由映射关系的功能,自行创建路由匹配规则。实现方式很简单,只需要在 API 网关程序中增加如下 Bean 创建即可:
(1)PatternServiceRouteMapper 对象可以让开发者通过正则表达式来自定义服务与路由映射的的生成关系。构造函数的参数说明:
  • 第一个参数是用来匹配服务名称是否符合该自定义规则的正则表达式
  • 第二个参数则是定义根据服务名中定义的内容转换出的路径表达式规则。
(2)当开发者在 API 网关中定义了 PatternServiceRouteMapper 实现之后:
  • 只要符合第一个参数定义规则的服务名,都会优先使用该实现构建出的路径表达式
  • 如果没有匹配上的服务则还是会使用默认的路由映射规则,即采用完整服务名作为前缀的路径表达式。
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

    @Bean
    public PatternServiceRouteMapper serviceRouteMapper() {
        return new PatternServiceRouteMapper("(?<name>^.+)-(?<version>v.+$)",
                "${version}/${name}");
    }

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}

(4)重启 API 网关程序,会发现之前那三个微服务的路径表达式规则会变成如下形式:
  • /v1/userservice
  • /v2/userservice
  • /v1/orderservice
评论

全部评论(0)

回到顶部