Version: Next

Gateway 搭建

cloud-gateway-gateway9527

POM

  • 核心是 gatewayeureka-client
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
提示

不要引入 springboot web 和 actuator,否则 Spring Cloud Gateway 会报错

完整pom依赖
<dependencies>
<dependency><!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>org.example</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

YAML

application.yaml
server:
port: 9527
spring:
application:
name: cloud-gateway
eureka:
instance:
hostname: cloud-gateway-service
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/ # 从本机 host 读取 ip 地址

主启动类

@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class, args);
}
}

路由映射

9527 网关如何做路由映射

  • cloud-provider-payment8001 查看 controller 的路由

    8001 微服务的 Controller 接口
    @GetMapping("/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
    Payment payment = paymentService.getPaymentById(id);
    return payment != null ? new CommonResult<>(200, "查询成功,端口号: " + serverPort, payment) :
    new CommonResult<>(444, "查询失败", null);
    }
    @GetMapping("/payment/lb")
    public String getPaymentLB() {
    return serverPort;
    }
  • 不希望直接暴露 8001,希望在外面套一层网关 9527

YAML

  • 添加 Spring Cloud Gateway 路由配置
  • 因为我的 8001 项目端口写错了,写成了 8081 ,因此将错就错配置成 8081
添加了网关配置的YAML
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
uri: http://localhost:8081
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由 根据8001的Controller写的
- id: payment_route2
uri: http://localhost:8081
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由 根据8001的Controller写的
eureka:
instance:
hostname: cloud-gateway-service
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/

测试

  • 启动 7001、启动 8001
  • 启动 9257 网关
  • 访问 Eureka Server 注册中心,可以看到 80019527 网关都注册到了注册中心

  • 访问 http://localhost:8081/payment/get/2 可以正常得到相应
  • 访问 http://localhost:9527/payment/get/2,可以获得相同的响应,网关将路由从 9527 映射到了 8081


路由网关的两种配置方式

  1. application.yaml 中配置
  2. 代码注入 RouteLocatorBean

案例

  • 利用本地 9527 网关,将本地路由映射到 百度新闻 的公开万维网网址上
  • 采用写配置类注入 Bean 的方式

GatewayConfig

@Configuration
public class GatewayConfig {
/**
* 配置了一个id为route-name的路由规则
* 当访问地址 http://localhost:9527/guonei时会自动转发到地址: http://news.baidu.com/guonei
*
* @param builder
* @return
*/
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_baidu1",
r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
@Bean
public RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_baidu2",
r -> r.path("/guoji")
.uri("http://news.baidu.com/guoji")).build();
return routes.build();
}
}

现在,当访问地址 http://localhost:9527/guonei时会自动转发到地址: http://news.baidu.com/guonei


动态路由配置

  • 默认情况下 Gateway 会根据注册中心的注册服务列表,以注册中心上 微服务名 为路径创建 动态路由 进行转发,从而实现动态路由的功能
  • 为了观察动态路由,需要至少两个服务端微服务,即 注册中心 7001 + 两个服务端微服务 8001 + 8002

YAML

修改 9527 网关 YAML 配置,实现动态路由

  • 需要注意的是 URI 的协议为 lb,表示启用 Gateway 负载均衡功能(基于 Ribbon)
  • lb://serviceName 是Spring Cloud Gateway 在微服务中自动为我们创建的负载均衡 URI
    • uri: http://localhost:8081 改为 uri: lb://cloud-payment-service

测试

多次访问 http://localhost:9527/payment/lb ,可以看到微服务端口在 80018002 间切换