默谷资源网

专业网站建设资源库

为什么微服务架构一定要有网关?(微服务架构中服务网关的作用是)

我们先来看下微服务网关的定义。

微服务网关是指为前端或客户端提供的统一服务入口,用于处理后端程序的通用逻辑,诸如:认证鉴权、动态路由、限流熔断、API监控等。

网关在微服务架构中所处的生态位,如下图所示:

认证鉴权:对用户请求进行识别判定,拦截非法请求,保障系统安全性。

动态路由:按照配置规则,动态地将用户请求路由到不同的微服务集群上。

限流熔断:旨在提升高并发场景下的系统可用性。

限流,控制单位时间内的请求流量,防止突发流量压垮后端服务,确保系统资源合理分配。

熔断,当下游非核心服务出现故障(如超时、异常)时,快速中断请求链路并返回预设响应,避免故障扩散引发雪崩效应。

API监控:通过集成多维度监控工具,实现对 API 请求的全链路追踪、性能指标收集与可视化分析,帮助开发者实时掌握网关流量状态与系统健康度。

接下来我们以Spring Cloud Gateway为例,看看这些功能是如何实现的,再回答“为什么微服务架构一定要有网关”这个问题,这样逻辑会清晰很多。

认证鉴权

Spring Cloud Gateway实现认证鉴权的核心是通过过滤器链(Filter Chain)拦截请求,结合安全框架(如 Spring Security)或自定义逻辑对用户身份和权限进行验证。

目前主流的认证鉴权方式是基于JWT来实现的,由

..三部分组成,具备无状态性、跨域支持和灵活扩展等优点。

代码实现如下:

@Component
public class JwtAuthFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        try {
            String jwtToken = token.substring(7); // 去掉 "Bearer " 前缀
            List<String> roles = JwtValidator.getRoles(jwtToken);
            // 检查角色是否匹配(示例:仅允许 ROLE_ADMIN 访问)
            if (!roles.contains("ROLE_ADMIN")) {
                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
                return exchange.getResponse().setComplete();
            }
        } catch (JwtException e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return -1; // 优先级
    }
}

动态路由

Spring Cloud Gateway可通过与Nacos、Apollo等配置中心配合的方式实现动态

路由,由配置中心管理路由配置,Gateway监听配置变化并动态更新路由。

配置中心中的路由规则如下:

[  {    "id": "user-service",    "predicates": [{"name": "Path", "args": {"pattern": "/api/user/**"}}],
    "filters": [{"name": "StripPrefix", "args": {"parts": 1}}],
    "uri": "lb://user-service",
    "order": 0
  }
]

然后在代码中对路由配置变化进行监听:

@Component  
public class NacosRouteDefinitionRepository implements RouteDefinitionRepository {  
    @Autowired  
    private NacosConfigManager nacosConfigManager;  

    @Override  
    public Flux<RouteDefinition> getRouteDefinitions() {  
        // 从 Nacos 加载路由配置:ml-citation{ref="6,8" data="citationList"}  
        return Flux.fromIterable(loadRoutesFromNacos());  
    }  

    @EventListener  
    public void onRefreshRoutesEvent(RefreshRoutesEvent event) {  
        // 触发路由更新:ml-citation{ref="6" data="citationList"}  
    }  
}  

限流熔断

对于限流熔断,目前的主流技术方案,是通过Spring Cloud Alibaba的Sentinel组件进行实现。

我们可以在Sentinel自带的控制台中进行精细化限流熔断参数配置,并可以实时生效。

如下图所示:

限流方面,我们可以简单粗暴地对Spring Cloud Gateway进行整体限流,也可以按需进行更加精细化的多维度限流。

比如:

(1)可以通过精确、前缀和正则表达式的方式进行API分组,对不同分组设置不同的限流策略。

(2)可以根据用户ID或外部系统编码进行限流,相比较于整体限流,这样可以更好地防止资源倾斜。

API监控

如上文所述,Sentinel是支持动态配置并实时生效的,但我们实时修改配置一定是需要一句的,这个依据就是对Spring Cloud Gateway中的API进行监控。

目前行业内的主流做法是,集成Prometheus监控平台进行数据收集和存储,并通过Grafana进行API指标(QPS、响应时间、错误率等)的可视化展示。

Spring Cloud Gateway还可以与Spring Cloud Sleuth + Zipkin进行集成,自动追踪请求在多个服务间的流转路径,记录耗时、状态码等关键信息,提升工程师的问题排查效率。

对于C端的高并发系统(QPS 10000+),我们可以调整采用率的方式来减轻存储压力,如:
spring.sleuth.sampler.probability = 0.1。

与此同时,我们还可以在代码中对关键业务接口专门配置注解,以使其进行强制采样。@Trace(sampler = Sampler.ALWAYS_SAMPLE)

网关的必要性

我们把网关所涉及到的功能梳理一遍后,接下来聊下“为什么微服务架构一定要有网关”。

如果没有网关层的话,那路由调用的工作只能由前端或客户端来完成,一定程度上增加了它们的工作复杂度。

如果没有网关层的话,那认证鉴权、限流熔断、API监控等工作只能由每个微服务都实现一遍,增加了很多重复的代码和工作量。

这两种副作用显然都不是我们想要看到的。

接下来我们再从系统架构的角度聊下微服务网关存在的意义。

系统架构设计通常有两个思路,那就是分治化和中心化。

分治化,其思路是将复杂问题进行拆解简化并逐个击破,而中心化则是将散点问题集中在一起进行解决,以起到提效的目的。

如果说我们将系统从单体架构拆分为微服务架构是分治化的思路,那网关层的中心化引入,则是在一定程度上弥补微服务拆分后所带来的研发效率问题。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言