微服务网关-Spring Cloud Gateway(上)

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 微服务网关-Spring Cloud Gateway(上)

正文


一、什么是网关?


       网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同层--应用层。-----摘自《百度百科》


二、Spring Cloud Gateway 原理


参考官网spring-cloud-gateway


三、构建简单的网关项目


pom文件如下


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.xiaojie</groupId>
    <artifactId>xiaojie-gateway</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
    </parent>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2021.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.0.2</version>
        </dependency>
        <!-- Feign Client for loadBalancing -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
            <version>3.0.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.0.2</version>
        </dependency>
        <!-- Feign Client for loadBalancing -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
            <version>3.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!-- mysql 依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 阿里巴巴数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.vladimir-bukhtoyarov/bucket4j-core -->
        <dependency>
            <groupId>com.github.vladimir-bukhtoyarov</groupId>
            <artifactId>bucket4j-core</artifactId>
            <version>6.0.1</version>
        </dependency>
    </dependencies>
</project>


启动类和简单api省略


四、路由谓词工厂


server:
  port: 80
spring:
  application:
    name: xiaojie-gateway
  cloud:
    gateway:
      routes:
#        - id: test_route
#          uri: https://www.baidu.com/
#          filters:
#            #这个意思是截取第一个前缀后访问 比如,请求/name/bar/foo,去除掉前面一个前缀之后,最后转发到目标服务的路径为/bar/foo
#            - StripPrefix=1
#          predicates:
#            - Path=/test #路径拦截
#             #ZonedDateTime dateTime = ZonedDateTime.now(); java8之后ZonedDateTime时间
#            - After=2021-07-14T09:51:55.052+08:00[Asia/Shanghai]
            #- Before=2021-07-15T09:51:55.052+08:00[Asia/Shanghai]
            #- Between=2021-07-14T09:51:55.052+08:00[Asia/Shanghai],2021-07-15T09:51:55.052+08:00[Asia/Shanghai]
            #- Cookie=xiaojie, [a-z]   #匹配cookie名字满足后面表达式的时候
            #- Header=X-Request-Id, \d+ # 匹配请求头中X-Request-Id 为数字的
            #- Host=**.xiaojie.com #匹配域名路由
            #- Method=GET,POST #拦截方法是get post 的请求
            #- Query=red, gree. #如果请求包含red其值与正则gree.表达式匹配的查询参数,则前面的路由匹配,因此green和greet将匹配
            #- RemoteAddr=192.168.1.1/24 #匹配ip
        #一下是权重路由匹配
        - id: weight_high
          uri: https://www.baidu.com
          predicates:
            - Weight=group1, 8
        - id: weight_low
          uri: https://www.sina.com
          predicates:
            - Weight=group1, 2


五、网关集群


555.jpg


通过Nginx转发到网关服务,网关经过轮训算法,或者其他的算法,转发到真实的服务器,进行服务的访问,下面开始配置。


网关端的配置文件


server:
  port: 82
####服务网关名称
spring:
  application:
    name: xiaojie-gateway
  cloud:
    gateway:
          ###路由策略
          routes:
            ###根据我们的服务名称查找地址实现调用
            - id: member
              #uri: http://127.0.0.1:8090
              uri: lb://xiaojie-member/ #服务的名称
              filters:
                - StripPrefix=1
              ###匹配规则
              predicates:
                - Path=/member/**
            #开启服务注册中心获取服务
          discovery:
            locator:
              enabled: true
    nacos:
      discovery:
        #注册地址
        server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
        #是否开启nacos注册
        enabled: true
        #账号
        username: xiaojie
        #密码
        password: nacos
        #命名空间 ,一定要对应上自己注册的服务的命名空间
        namespace: 28eb29ea-5a04-4714-8ae8-77d37c01166a
        #分组
        group: DEV_GROUP


会员服务端的配置文件


spring:
  application:
     name: xiaojie-member
  cloud:
    nacos:
      config:
        #前缀
        prefix: xiaojie-member
        #地址
        server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
        #扩展名
        file-extension: yaml
        #命名空间
        namespace: 28eb29ea-5a04-4714-8ae8-77d37c01166a
        #分组
        group: DEV_GROUP
        #开关
        enabled: true
        #动态刷新配置
        refresh-enabled: true
      discovery:
        #注册地址
        server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
        #是否开启nacos注册
        enabled: true
        #账号
        username: xiaojie
        #密码
        password: nacos
        #命名空间
        namespace: 28eb29ea-5a04-4714-8ae8-77d37c01166a
        #分组
        group: DEV_GROUP


Nginx添加如下配置


upstream xiaojie_gateway{
    server 127.0.0.1:81;
    server 127.0.0.1:82;
  }
  server {
        listen       80;
        server_name  gateway.xiaojie.com;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            proxy_pass http://xiaojie_gateway;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }       
    }


在网关中添加以下filter


package com.xiaojie.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
 * @Description: 配置token过滤器
 * @author: xiaojie
 * @date: 2021.07.14
 */
@Component
@Slf4j
public class TokenFilter implements GlobalFilter {
    @Value("${server.port}")
    private String serverPort;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取参数
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if(!StringUtils.hasText(token)){
            //token为空转发到其他的地址
            ServerHttpResponse response = exchange.getResponse();
            //
            response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            String msg = "token not is null ";
            DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
            return response.writeWith(Mono.just(buffer));
        }
        // 在请求头中存放serverPort serverPort
        ServerHttpRequest request = exchange.getRequest().mutate().header("serverPort", serverPort)
                .build();
        log.info("端口号是...............{}"+serverPort);
        return chain.filter(exchange.mutate().request(request).build());
    }
}


访问http://gateway.xiaojie.com/member/getMember?token=456 可以看到实现了集群效果。

相关文章
|
29天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
53 2
|
13天前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
Gateway服务网关
28 1
Gateway服务网关
|
1月前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
29天前
|
JSON Java 数据格式
【微服务】SpringCloud之Feign远程调用
本文介绍了使用Feign作为HTTP客户端替代RestTemplate进行远程调用的优势及具体使用方法。Feign通过声明式接口简化了HTTP请求的发送,提高了代码的可读性和维护性。文章详细描述了Feign的搭建步骤,包括引入依赖、添加注解、编写FeignClient接口和调用代码,并提供了自定义配置的示例,如修改日志级别等。
76 1
|
1月前
|
人工智能 文字识别 Java
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
尼恩,一位拥有20年架构经验的老架构师,通过其深厚的架构功力,成功指导了一位9年经验的网易工程师转型为大模型架构师,薪资逆涨50%,年薪近80W。尼恩的指导不仅帮助这位工程师在一年内成为大模型架构师,还让他管理起了10人团队,产品成功应用于多家大中型企业。尼恩因此决定编写《LLM大模型学习圣经》系列,帮助更多人掌握大模型架构,实现职业跃迁。该系列包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构》等,旨在系统化、体系化地讲解大模型技术,助力读者实现“offer直提”。此外,尼恩还分享了多个技术圣经,如《NIO圣经》、《Docker圣经》等,帮助读者深入理解核心技术。
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
|
1月前
|
监控 Java 对象存储
监控与追踪:如何利用Spring Cloud Sleuth和Netflix OSS工具进行微服务调试
监控与追踪:如何利用Spring Cloud Sleuth和Netflix OSS工具进行微服务调试
43 1
|
2月前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
48 3
|
2月前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
102 5
|
2月前
|
前端开发 API 微服务
SpringCloud微服务之间使用Feign调用不通情况举例
SpringCloud微服务之间使用Feign调用不通情况举例
501 2
|
1月前
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
61 0