目录

  • 一、序言
  • 二、代码示例
    • 1、父工程spring-cloud-gateway-learning
    • 2、子工程spring-cloud-api-gateway
      • (1) pom.xml
      • (2) 配置文件和代码示例
    • 3、子工程spring-cloud-user-service
      • (1) pom.xml
      • (2) 配置文件
    • 4、子工程spring-cloud-message-service
      • (1) pom.xml
      • (2) 配置文件和代码示例
  • 三、测试结果
    • 1、集群负载均衡测试
    • 2、服务路由测试

一、序言

我们都知道Spring Cloud Gateway是一个基于Spring BootSpring WebFluxProject Reactor构建的高性能网关,旨在提供简单、高效的API路由。

Spring Cloud Gateway基于Netty运行,因此在传统Servlet容器中或者打成war包是不能正常运行的。


二、代码示例

这里我们注册中心选型的是Nacos,如果还没有安装Nacos,请参考:Nacos快速安装部署。

1、父工程spring-cloud-gateway-learning

 <modules><module>spring-cloud-api-gateway</module><module>spring-cloud-user-service</module><module>spring-cloud-message-service</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.boot.version>2.3.7.RELEASE</spring.boot.version><spring.cloud.version>Hoxton.SR12</spring.cloud.version><spring.cloud.alibaba.version>2.2.6.RELEASE</spring.cloud.alibaba.version><commons.lang3.version>3.12.0</commons.lang3.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons.lang3.version}</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring.cloud.alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

备注:具体Spring Cloud各版本说明请参考Spring Cloud Alibaba版本说明。

2、子工程spring-cloud-api-gateway

(1) pom.xml

<parent><groupId>com.universe</groupId><artifactId>spring-cloud-gateway-learning</artifactId><version>1.0-SNAPSHOT</version>
</parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>

(2) 配置文件和代码示例

  1. bootstrap.yml
spring:application:name: api-gateway
server:port: 9000
  1. application.yml
spring:cloud:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/user/**- id: message-serviceuri: lb://message-servicepredicates:- Path=/message/**nacos:discovery:server-addr: localhost:8848

如果URI以lb开头,比如如上配置中的lb://user-serviceSpring Cloud Gateway会用ReactiveLoadBalancerClientFilter 解析服务名为user-service的实例对应的实际host和端口,并做集群负载均衡。

这项功能通过全局过滤器ReactiveLoadBalancerClientFilter 实现,官网描述如下:

  1. RouteRecordGlobalFilter
@Slf4j
@Component
public class RouteRecordGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// RouteToRequestUrlFilter会把实际路由的URL通过该属性保存URI proxyRequestUri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);long start = System.currentTimeMillis();return chain.filter(exchange).then(Mono.fromRunnable(() -> {long end = System.currentTimeMillis();log.info("实际调用地址为:{},调用耗时为:{}ms", proxyRequestUri, (end - start));}));}@Overridepublic int getOrder() {// 优先级设为最低,先让RouteToRequestUrlFilter先调用return Ordered.LOWEST_PRECEDENCE;}
}

RouteRecordGlobalFilter 这个全局过滤器我们主要用来记录路由后的实际代理地址,以及调用耗时。

我们看下RouteToRequestUrlFilter的描述会发现实际路由地址会通过ServerWebExchange中名为ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的属性保存。

关于RouteToRequestUrlFilter的部分源码如下:

@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);if (route == null) {return chain.filter(exchange);}log.trace("RouteToRequestUrlFilter start");URI uri = exchange.getRequest().getURI();boolean encoded = containsEncodedParts(uri);URI routeUri = route.getUri();if (hasAnotherScheme(routeUri)) {// this is a special url, save scheme to special attribute// replace routeUri with schemeSpecificPartexchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR,routeUri.getScheme());routeUri = URI.create(routeUri.getSchemeSpecificPart());}if ("lb".equalsIgnoreCase(routeUri.getScheme()) && routeUri.getHost() == null) {// Load balanced URIs should always have a host. If the host is null it is// most// likely because the host name was invalid (for example included an// underscore)throw new IllegalStateException("Invalid host: " + routeUri.toString());}URI mergedUrl = UriComponentsBuilder.fromUri(uri)// .uri(routeUri).scheme(routeUri.getScheme()).host(routeUri.getHost()).port(routeUri.getPort()).build(encoded).toUri();exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);return chain.filter(exchange);}

备注:更多关于全局过滤器的介绍请参考 Spring Cloud Gateway全局过滤器。

3、子工程spring-cloud-user-service

(1) pom.xml

<parent><groupId>com.universe</groupId><artifactId>spring-cloud-gateway-learning</artifactId><version>1.0-SNAPSHOT</version>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>

(2) 配置文件

  1. bootstrap.yml
spring:application:name: user-service
server:servlet:context-path: /user---
spring:profiles: user-service-master
server:port: 9091---
spring:profiles: user-service-slave
server:port: 9092
  1. application.yml
spring:cloud:nacos:discovery:server-addr: localhost:8848
  1. UserController
@RestController
public class UserController {@GetMapping("/info")public Map<String, Object> getUserInfo() {Random random = new Random();int waitTime = random.nextInt(1000);LockSupport.parkNanos(1000 * 1000 * waitTime);Map<String, Object> result = new HashMap<>();result.put("name", "Nick");result.put("age", 25);return result;}
}

4、子工程spring-cloud-message-service

(1) pom.xml

<parent><groupId>com.universe</groupId><artifactId>spring-cloud-gateway-learning</artifactId><version>1.0-SNAPSHOT</version>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>

(2) 配置文件和代码示例

  1. bootstrap.yml
spring:application:name: message-service
server:servlet:context-path: /message---
spring:profiles: message-service-master
server:port: 9093---
spring:profiles: message-service-slave
server:port: 9094
  1. application.yml
spring:cloud:nacos:discovery:server-addr: localhost:8848
  1. MessageController
@RestController
public class MessageController {@GetMapping("/info")public Map<String, Object> getMessageInfo() {Random random = new Random();int waitTime = random.nextInt(1000);LockSupport.parkNanos(1000 * 1000 * waitTime);Map<String, Object> result = new HashMap<>();result.put("id", 1);result.put("title", "我爱中国");return result;}
}

三、测试结果

分别启动api-gateway、指定概要文件启动两个user-service服务实例、和两个message-service服务实例,查看Nacos控制台。

可以看到,api-gateway启动了一个服务实例,user-service和message-service都启动了两个服务实例。

备注:IDEA运行时指定Active Profiles即可。

1、集群负载均衡测试

连续访问http://localhost:9000/user/info,可以看到user-service集群服务实例被轮询调用。

2、服务路由测试

分别访问 http://localhost:9000/user/infohttp://localhost:9000/message/info,我们可以看到基于路径匹配的服务路由分发是成功的。

Spring Cloud Gateway整合Nacos实现服务路由及集群负载均衡相关推荐

  1. Spring Cloud Gateway——2020.x以上版本HTTP 503 或 NoLoadBalancer[负载均衡]解决方案

    问题描述 config spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/** ...

  2. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...

  3. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战

    文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...

  4. Spring Cloud Gateway 整合 knife4j 聚合接口文档

    当系统中微服务数量越来越多时,如果任由这些服务散落在各处,那么最终管理每个项目的接口文档将是一件十分麻烦的事情,单是记住所有微服务的接口文档访问地址就是一件苦差事了.当如果能够将所有微服务项目的接口文 ...

  5. 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!

    今天这篇文章介绍一下Spring Cloud Gateway整合OAuth2.0实现认证授权,涉及到的知识点有点多,有不清楚的可以看下陈某的往期文章. 文章目录如下: 微服务认证方案 微服务认证方案目 ...

  6. spring react_使用Spring Cloud Gateway保护React式微服务

    spring react 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 所以你想 ...

  7. 使用Spring Cloud Gateway保护反应式微服务

    朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护. 所以你想完全反应,是吗? 大! ...

  8. react hooks_使用Spring Cloud Gateway保护React式微服务

    react hooks 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 所以你想完 ...

  9. Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用

    Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...

最新文章

  1. 科学界最牛的合影在这,能认全的都是大神!
  2. java robot 控制鼠标_Java-探索Robot类:[2]自动控制鼠标
  3. 1.MySQL基本体系
  4. STC10F10XE定时器中断输出10KHz的方波程序
  5. 大数据容器化-基于Kubernetes(k8s)构建spark运行环境
  6. Gradle个人笔记(未完)
  7. LeetCode 258 Add Digits
  8. Socket api接口--Send(),Recv()的长度问题
  9. mime.types
  10. sql 视图不排序_算法工程师SQL进阶:神奇的自连接与子查询
  11. C#中对txt文件的读写操作
  12. 庆贺:上传资源时已支持不允许动态调分
  13. 4.4 输入法图片 android,支持安卓4.4!搜狗输入法5.1新版发布
  14. 计算机专业wor知识,计算机专业毕业实习日记精选
  15. android 静默暗转_Android 7.0 静默安装
  16. 解决Linux终端无法复制粘贴现象
  17. python数据分析:客户价值分析案例实战
  18. mediacodec mp4v2应用
  19. Qt使用漂亮的图标和字体(Font Awesome)————附代码实例
  20. Android 实践:做一款新闻 APP

热门文章

  1. 寒假作死项目之贪吃蛇
  2. 微信小程序中获取用户微信运动信息
  3. 调用png格式图片时“libpng warning: iCCP: known incorrect sRGB profile”警告
  4. PowerDesigner-反向工程-mysql
  5. PostgreSQL之wal_keep_segments参数
  6. Android Studio中src/main/res/values中strings.xml文件中字符串使用
  7. PDB python调试
  8. Altium designer20使用出现的问题2----导出坐标文件缺失器件
  9. simplify3d 打印参数设置笔记
  10. WIFI Direct(WIFI P2P)