微服务系列详解-Part5:Spring Cloud Zuul代理作为API网关

25 篇文章 0 订阅
本文深入讲解如何利用Spring Cloud Zuul构建API网关,探讨API网关的作用、优缺点,并通过实例展示如何配置和使用Zuul代理。通过Zuul,我们可以集中处理跨领域的关注点,如安全性,并实现客户端与微服务间的解耦。
摘要由CSDN通过智能技术生成

在本教程中,我们将学习如何将Spring Cloud Zuul代理用作API网关,这是微服务架构的重要组成部分。抽丝剥茧 细说架构那些事——【优锐课】

上篇文章说到,微服务系列详解-Part4:使用Netflix Hystrix的Spring Cloud断路器

在微服务架构中,可能有许多API服务和与API通讯的UI组件很少。到目前为止,许多基于微服务的应用程序仍使用整体的UI作为单个模块构建的整体式前端。您可能会选择使用微前端,在该微前端中,UI也被分解为与API通讯以获取相关数据的多个微服务。我们可以提供一个统一的代理接口,该接口将基于URL模式将调用委派给各种微服务,而不是让UI知道我们所有的微服务详细信息。在本文中,我们将学习如何使用Spring Cloud Zuul代理创建API网关。

在这篇文章中,我们将学习:
• 为什么我们需要一个API网关?
• 使用Spring Cloud Zuul代理实现API网关
• 使用Zuul过滤器解决跨领域关注点

API网关(也称为边缘服务)为一组微服务提供统一的接口,因此客户端无需了解微服务内部结构的所有详细信息。但是,在微服务体系结构中使用API网关模式有一些优缺点。

优点:
• 为客户端提供更轻松的界面。
• 可用于防止将内部微服务结构暴露给客户端。
• 允许重构微服务,而无需强制客户端重构使用逻辑。
• 可以集中解决跨部门的问题,例如安全性,监视,速率限制等。

缺点:
• 如果未采取适当措施使其高度可用,则可能会成为单点故障。
• 各种微服务API的知识可能会渗入API网关。

Spring Cloud提供类似于Nginx的Zuul代理,可用于创建API网关。
让我们创建一个前端UI模块“ shoppingcart-ui”作为Spring Boot应用程序,该应用程序还充当Zuul代理。使用Web,Config Client,Eureka Discovery,Zuul启动器创建一个SpringBoot项目,并使用@EnableZuulProxy注释主入口点类。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<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>

ShoppingcartUiApplication.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@SpringBootApplication
public class ShoppingcartUiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShoppingcartUiApplication.class, args);
    }
}

由于我们正在使用Eureka Discovery;同样,来自具有URL模式/ service-id / 的代理的请求将被路由到在Eureka Server中注册的服务ID为“ service-id”的服务。

例如,从UI应用程序中,如果我们向http:// localhost:8080/catalog-service/products发出请求,则它将在Service Registry中查找ServiceID“ catalog-service”,并将带有URL/products的请求发送到以下其中一个 可用的目录服务实例。

为此,我们需要在Eureka Service Registry中注册“ shoppingcart-ui”。

bootstrap.properties
spring.application.name=shoppingcart-ui
server.port=8080
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

现在,通过这种配置,我们可以使用jQuery从目录服务中获取产品信息,如下所示:

$.ajax({
    url: '/catalog-service/products'
})
.done(function(data) {
    this.products = data;
}.bind(this));

在这里,从UI应用程序中,我们正在调用http://localhost:8080/catalog-service/products。假设目录服务已使用ServiceID"catalog-service"注册并在端口8181上运行,则此请求将转发到http://host:8181/products。但是,UI完全不知道实际的目录服务在哪里运行以及其主机名,端口号等。

我们还可以为URL使用通用前缀,例如"/api,"我们希望Zuul通过设置zuul.prefix属性来为其代理。

zuul.prefix=/api

现在,从用户界面,我们可以在http://localhost:8080/api/catalog-service/products上请求获取产品。默认情况下,Zuul将删除前缀并转发请求。

您还可以如下自定义服务的路径映射:

zuul.routes.catalogservice.path=/catalog/
zuul.routes.catalogservice.serviceId=catalog-service

通过此配置,您可以使用URL http://localhost:8080/api/catalog/products,该URL将通过serviceId catalog-service转发到该服务。

默认情况下,所有在Eureka Server中注册的服务都将公开。您可以使用zuul.ignored-services属性来禁用此行为,并仅公开显式配置的服务。

zuul.ignored-services=*
zuul.routes.catalogservice.path=/catalog/**
zuul.routes.catalogservice.serviceId=catalog-service
zuul.routes.orderservice.path=/orders/**
zuul.routes.orderservice.serviceId=order-service

使用此配置,仅通过Zuul代理公开目录服务,订单服务,而不通过库存服务公开。
由于Zuul充当了我们所有微服务的代理,因此我们可以使用Zuul服务来实现一些跨领域的问题,例如安全性,速率限制等。一个常见的用例是将Authentication标头转发到所有下游服务。

通常在微服务中,我们将使用OAuth服务进行身份验证和授权。客户端通过身份验证后,OAuth服务将生成一个令牌,该令牌应包含在对其他微服务的请求中,因此无需分别为每个服务都对客户端进行身份验证。我们可以使用Zuul过滤器来实现这样的功能。

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
public class AuthHeaderFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE;
    }
    @Override
    public int filterOrder() {
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (request.getAttribute("AUTH_HEADER") == null) {
            //generate or get AUTH_TOKEN, ex from Spring Session repository
            String sessionId = UUID.randomUUID().toString();
            ctx.addZuulRequestHeader("AUTH_HEADER", sessionId);
        }
        return null;
    }
}

我们使用RequestContext.addZuulRequestHeader()将AUTH_HEADER添加为请求标头,该标头将转发到下游服务。我们需要将其注册为Spring bean。

@Bean
AuthHeaderFilter authHeaderFilter() {
    return new AuthHeaderFilter();
}

感谢阅读!下篇继续:微服务系列详解- Part 6:使用Spring Cloud Sleuth和Zipkin进行分布式跟踪
另外还有一些资源分享给各位,需要的可以免费领取~
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值