通过Gateway实现负载均衡有两种方式,一种是自动的负载均衡,一种是手动的负载均衡。
Gateway还提供了和Zuul类似的自动路由规则,具体配置如下:
discovery.locator.enabled= true 这个配置默认为false,但是如果为true,就是开启了通过serviceId转发到具体的服务实例。即:“localhost:9999/ServiceID/demo/**”。
所以我们修改一下cloud-gateway-service-9999网关服务的application.yml配置,屏蔽掉网关的路由的routes配置
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能
#是否与服务发现组件进行结合,通过serviceId转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能
# routes: # 路由
# - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
# uri: http://localhost:9001/nacos-provider # 匹配提供服务的路由地址
# predicates: # 断言
# - Path=/demo/** # 断言,路径相匹配进行路由
在配置好这些以后,重启服务,我们可以直接通过服务名称来进行访问Nacos中注册的服务和对应的接口,例如:http://localhost:9999/nacos-provider/demo/hello(中间多了一个服务名称:/nacos-provider)
Gateway在开启了自动路由之后,自带负载均衡
首先,我们再创建一个服务demo-9002
具体配置如下:
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.examplegroupId>
<artifactId>spring-cloud-gatewayartifactId>
<version>0.0.1-SNAPSHOTversion>
parent>
<groupId>com.songroupId>
<artifactId>demo-9002artifactId>
<version>0.0.1-SNAPSHOTversion>
<name>demoname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
dependencies>
project>
application.yml配置:
server:
port: 9002
spring:
application:
name: nacos-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoint:
web:
exposure:
include: '*'
由于此服务也是配合Nacos使用,所以启动器要加上@EnableDiscoveryClient注解:
新建DemoController文件,里面的hello方法与springcloudalibaba-nacos-9001服务中的DemoController保持一致:
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/demo") //路由路径
public class DemoController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/hello")
public String getServerPort(){
return "Hello! port: "+ serverPort;
}
}
然后我们将cloud-gateway-service-9999网关服务,以及2个微服务springcloudalibaba-nacos-9001、demo-9002启动起来
接着,我们访问地址:http://localhost:9999/nacos-provider/demo/hello, 可以看到是走的9001服务
接着,我们刷新页面再次访问,可以看到是走的9002服务,所以Gateway在开启了自动路由之后(discovery.locator.enabled=true)自带负载均衡功能
在以上的配置中,其实是有问题的,问题在于当前的服务名称暴露,并且太过于灵活,那么如果想解决的话,其实我们可以进行手动配置(将uri配置中的http改为lb,lb代表开启负载均衡)。
修改一下cloud-gateway-service-9999网关服务的application.yml配置:
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能
#是否与服务发现组件进行结合,通过serviceId转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能
routes: # 路由
- id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: lb://nacos-provider # 匹配提供服务的路由地址 lb://代表开启负载均衡
predicates: # 断言
- Path=/demo/** # 断言,路径相匹配进行路由
注意:如果我们配置了discovery.locator.enabled= true,并且配置了路由routes规则之后,会根据predicates断言地址匹配对应的服务,就不会走自动路由配置。
接着,我们重启网关服务cloud-gateway-service-9999,然后访问:http://localhost:9999/demo/hello
再次访问:
此时,就实现了手动的负载均衡,服务名称就被隐藏了。
上面我们讲到了http方式和lb注册中心服务方式,其实还有一种websocket方式
在gateway中配置uri配置有三种方式,包括:
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能
#是否与服务发现组件进行结合,通过serviceId转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能
routes: # 路由
- id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: http://localhost:9001/nacos-provider
predicates: # 断言
- Path=/demo/** # 断言,路径相匹配进行路由
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能
#是否与服务发现组件进行结合,通过serviceId转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能
routes: # 路由
- id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: ws://localhost:8888
predicates: # 断言
- Path=/demo/** # 断言,路径相匹配进行路由
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能
#是否与服务发现组件进行结合,通过serviceId转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能
routes: # 路由
- id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: lb://nacos-provider
predicates: # 断言
- Path=/demo/** # 断言,路径相匹配进行路由