背景:本想找个简单例子看下,无奈版本依赖太过复杂,花了点时间。记录下吧
使用Spring Cloud Gateway作为网关服务,Nacos作为注册中心,实现对子服务的负载均衡访问。简单例子。
环境要求:JDK1.8、nacos 1.3.0服务端。
一、gateway-main-nacos服务端:
完整pom文件:
<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.example</groupId>
<artifactId>gateway-main-nacos</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
<!-- Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.1</version>
</dependency>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
完整的yml配置文件:
server:
port: 8888
spring:
application:
name: gateway-service
main:
web-application-type: reactive
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos 服务器地址
namespace: namespace_xxx
config:
server-addr: localhost:8848 # Nacos 配置中心地址
file-extension: yaml
gateway:
discovery:
locator:
enabled: true
routes:
- id: neo_route
uri: http://www.ityouknow.com
predicates:
- Path=/spring-cloud
# - id: add_request_parameter_route
# uri: http://localhost:8889
# filters:
# - AddRequestParameter=foo, bar
# predicates:
# - Method=GET
- id: lb_nacos
uri: lb://user-service #会进行服务负载均衡
filters:
- AddRequestParameter=foo, bar123
predicates:
- Path=/user/** # 匹配 /user/** 路径的请求
- id: lb_nacos01
uri: lb://user-service
filters:
- StripPrefix=1 # 去掉前缀 /user01
predicates:
- Path=/user01/** # 匹配 /user01/** 路径的请求
GatewayApplication启动类:
package com.neo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
二、 路由的子服务(可以发布两个服务,达到负载均衡的效果)
完整pom文件:
<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.example</groupId>
<artifactId>user-service</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
完整的yml文件:
server:
port: 8889
spring:
application:
name: user-service
#main:
# web-application-type: reactive
cloud:
gateway:
discovery:
locator:
enabled: true
nacos:
discovery:
server-addr: localhost:8848 # Nacos 服务器地址
namespace: namespace_xxx #nacos命名空间,修改为自己定义的
config:
server-addr: localhost:8848 # Nacos 配置中心地址
namespace: namespace_xxx
file-extension: yaml
子服务启动类:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
对应测试的Controller类:
@RestController
public class HelloController {
@GetMapping("/hello")
public String index() {
return "hello world!";
}
@GetMapping("/user/hello")
public String indexUser() {
return "hello world user!";
}
@RequestMapping("/user/foo")
public String foo(String foo) {
return "hello "+foo+"!";
}
}
三、测试
本地启动gateway-main-nacos、user-service、user-service-1。 访问 http://localhost:8888/user/hello,多次访问发现会返回 hello world user! 或者 hello world user,another!。达到负载均衡的效果。
访问这个地址也可以看到同样的效果, http://localhost:8888/user01/hello
两个url不同的路由匹配规则。
四、遇到的问题:
1.#允许bean Service循环依赖
spring.main.allow-circular-references=true
2.#Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
#同时使用Spring MVC和Spring Cloud Gateway
spring.main.web-application-type=reactive
3.SpringCloud-Gateway搭配服务注册Nacos进行lb动态路由遇到的问题
高版本的spring-cloud-alibaba-dependencies依赖中去除了ribbon依赖,若想能通过Gateway网关找到对应的微服务,需要引入loadbalancer依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
参考的文档:http://www.ityouknow.com/springcloud/2019/01/19/spring-cloud-gateway-service.html
源码地址:https://github.com/tracysw/Spring-Cloud-Gateway-Samples