用vscode创建spring boot应用,软件环境:
spring 3.0.6
alibaba cloud 2022.0.0.0-RC2
spring initial 时初始化引入插件:Gateway, Spring Boot Actuator
【注意】业务节点的服务名不能用下划线,否则会报"Whitelabel Error Page"错误
项目的pom.xml完整配置如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cloudservice</groupId>
<artifactId>gateway_service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway_service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
<spring-alibaba-cloud.version>2022.0.0.0-RC2</spring-alibaba-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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-alibaba-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
删除项目的src/main/resources/application.protertity文件,新建文件:src/main/resources/bootstrap.yml用于启动时从nacos读取网关配置,bootstrap.yml文件内容如下:
spring:
profiles:
active: dev
application:
name: gateway_service
cloud:
nacos:
# 动态服务发现服务
discovery:
# nacos服务地址, 正式时可以用域名或云的动态负载产品来实现多配置中心节点的动态负载
server-addr: 192.168.10.111:8848
# nacos认证信息
username: nacos
password: nacos
# 如果没有指定命令空间,则默认命令空间为PUBLIC,如果指定需要写ID
namespace:
# 动态配置服务
config:
# nacos config服务器的地址
server-addr: 192.168.10.111:8848
# nacos认证信息
username: nacos
password: nacos
file-extension: yml
# 如果没有指定命令空间,则默认命令空间为PUBLIC,如果指定需要写ID
namespace:
# 如果没有配置Group,则默认值为DEFAULT_GROUP
group: DEFAULT_GROUP
# 从Nacos读取配置项的超时时间
timeout: 5000
# 长轮询超时时间
config-long-poll-timeout: 10000
# 轮询的重试时间
config-retry-time: 2000
# 长轮询最大重试次数
max-retry: 3
# 开启监听和自动刷新
refresh-enabled: true
# Nacos的扩展配置项,数字越大优先级越高
extension-configs:
- dataId: actuator.yml
group: COMMON_GROUP
# 动态刷新
refresh: true
# - dataId: rabbitmq-config.yml
# group: EXT_GROUP
# refresh: true
网关的nacos主配置:
命名空间用默认的public
Data ID是:gateway_service-dev.yml
Group是:DEFAULT_GROUP
配置格式:YAML
配置内容如下:
management:
# actuator的监控端口
server:
port: 7001
endpoint:# actuator开启网关监控功能
gateway:
enabled: true# 网关服务端口
server:
port: 6001
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
filters:
# StripPrefix 数字表示要截断的路径的数量
- StripPrefix=1
启动类加上简单的OpenFeign的负载均衡和远程调用实现,下一章节才详细说明动态网关路由的实现和dubbo的集成,启动类代码如下:
package com.cloudservice.gateway_service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
另外创建转发的测试业务节点:order-service, pom.xml和bootstrap.yml基本与网关相同,不加载gateway依赖就行,nacos配置只要配置:actuator的监控端口和web服务端口即可;同时加入默认访问路径的Controller实现HomeController, 代码如下:
package com.cloudservice.orderservice;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
src/main/resources/templates/home.html模板代码如下:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Order Home</title>
</head>
<body>
<h1>Welcome to Order Home.</h1>
</body>
</html>
分别启动网关gateway节点和order-service节点,在网页输入地址:
http://192.168.10.111:6001/order/
即可看到:
同时,可以通过actuator监控的地址,查看当前路由信息,访问地址:http://192.168.10.111:7001/actuator/gateway/routes
返回内容:
[
{
"predicate": "Paths: [/order-service/**], match trailing slash: true",
"metadata": {
"nacos.instanceId": null,
"nacos.weight": "1.0",
"nacos.cluster": "DEFAULT",
"nacos.ephemeral": "true",
"nacos.healthy": "true",
"management.port": "7002",
"preserved.register.source": "SPRING_CLOUD"
},
"route_id": "ReactiveCompositeDiscoveryClient_order-service",
"filters": [
"[[RewritePath /order-service/?(?<remaining>.*) = '/${remaining}'], order = 1]"
],
"uri": "lb://order-service",
"order": 0
},
{
"predicate": "Paths: [/gateway_service/**], match trailing slash: true",
"metadata": {
"nacos.instanceId": null,
"nacos.weight": "1.0",
"nacos.cluster": "DEFAULT",
"nacos.ephemeral": "true",
"nacos.healthy": "true",
"management.port": "7001",
"preserved.register.source": "SPRING_CLOUD"
},
"route_id": "ReactiveCompositeDiscoveryClient_gateway_service",
"filters": [
"[[RewritePath /gateway_service/?(?<remaining>.*) = '/${remaining}'], order = 1]"
],
"uri": "lb://gateway_service",
"order": 0
},
{
"predicate": "Paths: [/order/**], match trailing slash: true",
"route_id": "order-service",
"filters": [
"[[StripPrefix parts = 1], order = 1]"
],
"uri": "lb://order-service",
"order": 0
}
]
【注意】
1. 192.168.10.111是我自己本地架设的centos8的机器地址,按实际的网关所在机器地址配置
2. 如果网页访问不了网关端口,确认网关等应用都启动的情况下,用telnet检查防火墙是否开放了端口,没有则用firewall-cmd命令开放相应的端口
3. actuator监控端口绝不能对外开放,否则会带来的安全风险
4. spring.cloud.nacos.discovery用于向nacos注册中心注册和发现服务,服务间只能发现和访问有相同的namespace和group的已注册的服务