Spring Cloud Gateway整合Nacos实现服务路由及集群负载均衡
目录
- 一、序言
- 二、代码示例
- 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 Boot、Spring WebFlux、Project 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) 配置文件和代码示例
- bootstrap.yml
spring:application:name: api-gateway
server:port: 9000
- 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-service
,Spring Cloud Gateway会用ReactiveLoadBalancerClientFilter
解析服务名为user-service
的实例对应的实际host和端口,并做集群负载均衡。
这项功能通过全局过滤器ReactiveLoadBalancerClientFilter
实现,官网描述如下:
- 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) 配置文件
- 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
- application.yml
spring:cloud:nacos:discovery:server-addr: localhost:8848
- 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) 配置文件和代码示例
- 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
- application.yml
spring:cloud:nacos:discovery:server-addr: localhost:8848
- 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/info
、http://localhost:9000/message/info
,我们可以看到基于路径匹配的服务路由分发是成功的。
Spring Cloud Gateway整合Nacos实现服务路由及集群负载均衡相关推荐
- Spring Cloud Gateway——2020.x以上版本HTTP 503 或 NoLoadBalancer[负载均衡]解决方案
问题描述 config spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/** ...
- Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...
- Spring Cloud Gateway 整合阿里 Sentinel网关限流实战
文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...
- Spring Cloud Gateway 整合 knife4j 聚合接口文档
当系统中微服务数量越来越多时,如果任由这些服务散落在各处,那么最终管理每个项目的接口文档将是一件十分麻烦的事情,单是记住所有微服务的接口文档访问地址就是一件苦差事了.当如果能够将所有微服务项目的接口文 ...
- 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!
今天这篇文章介绍一下Spring Cloud Gateway整合OAuth2.0实现认证授权,涉及到的知识点有点多,有不清楚的可以看下陈某的往期文章. 文章目录如下: 微服务认证方案 微服务认证方案目 ...
- spring react_使用Spring Cloud Gateway保护React式微服务
spring react 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 所以你想 ...
- 使用Spring Cloud Gateway保护反应式微服务
朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护. 所以你想完全反应,是吗? 大! ...
- react hooks_使用Spring Cloud Gateway保护React式微服务
react hooks 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 所以你想完 ...
- Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用
Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...
最新文章
- 科学界最牛的合影在这,能认全的都是大神!
- java robot 控制鼠标_Java-探索Robot类:[2]自动控制鼠标
- 1.MySQL基本体系
- STC10F10XE定时器中断输出10KHz的方波程序
- 大数据容器化-基于Kubernetes(k8s)构建spark运行环境
- Gradle个人笔记(未完)
- LeetCode 258 Add Digits
- Socket api接口--Send(),Recv()的长度问题
- mime.types
- sql 视图不排序_算法工程师SQL进阶:神奇的自连接与子查询
- C#中对txt文件的读写操作
- 庆贺:上传资源时已支持不允许动态调分
- 4.4 输入法图片 android,支持安卓4.4!搜狗输入法5.1新版发布
- 计算机专业wor知识,计算机专业毕业实习日记精选
- android 静默暗转_Android 7.0 静默安装
- 解决Linux终端无法复制粘贴现象
- python数据分析:客户价值分析案例实战
- mediacodec mp4v2应用
- Qt使用漂亮的图标和字体(Font Awesome)————附代码实例
- Android 实践:做一款新闻 APP
热门文章
- 寒假作死项目之贪吃蛇
- 微信小程序中获取用户微信运动信息
- 调用png格式图片时“libpng warning: iCCP: known incorrect sRGB profile”警告
- PowerDesigner-反向工程-mysql
- PostgreSQL之wal_keep_segments参数
- Android Studio中src/main/res/values中strings.xml文件中字符串使用
- PDB python调试
- Altium designer20使用出现的问题2----导出坐标文件缺失器件
- simplify3d 打印参数设置笔记
- WIFI Direct(WIFI P2P)