# 从浅入深 学习 SpringCloud 微服务架构(十一)--SpringCloudGateWay(1)

从浅入深 学习 SpringCloud 微服务架构(十一)–SpringCloudGateWay(1)

一、SpringCloudGateway:概述

1、Zuul 网关存在的问题

1.1 Zuul 中,整个请求的过程

首先将请求给 zuulservlet 处理,zuulservlet 中有一个 zuulRunner 对象,该对象中初始化了 Requestcontext: 作为存储整个请求的一些数据,并被所有的 zuulfilter 共享。

zuulRunner 中还有 FilterProcessor, FilterProcessor 作为执行所有的 zuulfilter 的管理器。

FilterProcessor 从 filterloader 中获取 zuulfilter,而 zuulfilter 是被 filterFileManager 所加载,并支持 groovy 热加载,采用了轮询的方式热加载。

有了这些 filter 之后,zuulservelet 首先执行的 Pre 类型的过滤器,再执行 route 类型的过滤器,最后执行的是 post 类型的过滤器。

如果在执行这些过滤器有错误的时候则会执行 error 类型的过滤器。执行完这些过滤器,最终将请求的结果返回给客户端。

1.2 在实际使用中我们会发现直接使用 Zuul 会存在诸多问题,包括:
  • 性能问题

Zuul1x 版本本质上就是一个同步 Servlet,采用多线程阻塞模型进行请求转发。

简单讲,每来一个请求,Servlet 容器要为该请求分配一个线程专门负责处理这个请求,直到响应返回客户端这个线程才会被释放返回容器线程池。

如果后台服务调用比较耗时,那么这个线程就会被阻塞,阻塞期间线程资源被占用,不能干其它事情。

我们知道 Servlet 容器线程池的大小是有限制的,当前端请求量大,而后台慢服务比较多时,很容易耗尽容器线程池内的线程,造成容器无法接受新的请求。

  • 不支持任何长连接,如 webspcket。

2、Zuul 网关的替换方案

  • Zuul2.x版本
  • SpringCloud Gateway

3、微服务网关 GateWay

Zuul 1.x 是一个基于阻塞 IO 的 APIGateway 以及 Servlet;
直到 2018年5月, u1 2.x(基于Netty,也是非阻塞的,支持长连接)才发布,但 Spring Cloud 暂时还没有整合计划。
Spring Cloud Gateway 比 Zuul1.x 系列的性能和功能整体要好。

3.1 Gateway 简介

Spring Cloud Gateway.是 Spring 官方基于 Spring5.0, Spring Boot 2.0 和 Project Reactor 等技术开发的网关,
旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式,统一访问接口。

SpringCloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 NetflixZUUL,
其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,
例如:安全,监控/埋点,和限流等。它是基于Nttey的响应式开发模式。

3.2 Spring Cloud Gateway 与Zuul 的性能对比
组件RPS(request per second)
Spring Cloud GatewayRequests/sec: 32213.38
Zuu11XRequests/sec: 20800.13

从结果可知,Spring Cloud Gateway 的 RPS 是 Zuul 的 1.6 倍。

3.3 springcloud gateway 网关 功能模块
  • 路由配置
  • 过滤器
  • 统-鉴权
  • 网关限流
  • 网关的高可用

二、SpringCloudGateway 路由:基本配置

1、前言:SpringCloudGateway 路由 核心概念:

1.1 路由(route) :

路由是网关最基础的部分,路由信息由一个 ID、一个目的 URL、一组断言工厂和一组 Filter 组成。如果断言为真,则说明请求 URL 和配置的路由匹配。

1.2 断言(predicates):

java8 中的断言函数,Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框架中的 ServerWebExchange。Spring Cloud Gateway 中的断言函数允许开发者去定义匹配来自 Http Request 中的任何信息,比如请求头和参数等。

1.3 过滤器(filter ):

一个标准的 Spring webFilter,Spring Cloud Gateway 中的 Filter 分为两种类型,分别是 Gateway Filter 和 Global Filter。过滤器 Filter 可以对请求和响应进行处理。

2、SpringCloudGateWay 网关:入门案例

1)创建工程,导入依赖坐标。
2)配置启动类
3)编写配置文件

2.1 SpringCloudGateWay 网关:入门案例–搭建环境,准备数据库。

— 创建数据库:
create database shop;

— 使用数据库:
use shop;

— 创建数据表:

	CREATE TABLE `tb_product` (`id` int NOT NULL AUTO_INCREMENT,`product_name` varchar(40) DEFAULT NULL COMMENT '名称',`status` int DEFAULT NULL COMMENT '状态',`price` decimal(10,2) DEFAULT NULL COMMENT '单价',`product_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述',`caption` varchar(255) DEFAULT NULL COMMENT '标题',`inventory` int DEFAULT NULL COMMENT '库存',PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3

— 插入数据:

insert into `tb_product` (`id`, `product_name`, `status`, `price`, `product_desc`, `caption`, `inventory`) values('1','iPhone 15 Pro','1','7999.00','iPhone 15 Pro 6.7 英寸或 6.1 英寸, 超视网膜 XDR 显示屏,ProMotion 自适应刷新率技术,钛金属搭配亚光质感玻璃背板, 灵动岛功能, A17 Pro 芯片,配备 6 核图形处理器, Pro 级摄像头系统,主摄 4800 万像素 | 超广角 | 长焦, 10 倍, 支持 USB 3, 视频播放最长可达 29 小时。 ','iPhone 15 Pro 巅峰之作','99');
2.2 SpringCloudGateWay 网关:入门案例–搭建环境–打开 idea 创建父工程

创建 artifactId 名为 spring_cloud_demo 的 maven 工程。

--> idea --> File --> New --> Project --> Maven Project SDK: ( 1.8(java version "1.8.0_131" ) --> Next --> Groupld : ( djh.it )Artifactld : ( spring_cloud_demo )Version : 1.0-SNAPSHOT--> Name: ( spring_cloud_demo )Location: ( ...\spring_cloud_demo\ )	--> Finish
2.3 SpringCloudGateWay 网关:入门案例–搭建环境–在父工程 spring_cloud_demo 的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>djh.it</groupId><artifactId>spring_cloud_demo</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>product_service</module><module>order_service</module><module>eureka_service</module><module>import_eurekaserver_test</module><module>api_zuul_service</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.6.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.4</version><scope>provided</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>http://repo.spring.io/libs-snapshot-local</url><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>http://repo.spring.io/libs-milestone-local</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-releases</id><name>Spring Releases</name><url>http://repo.spring.io/libs-release-local</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>http://repo.spring.io/libs-snapshot-local</url><snapshots><enabled>true</enabled></snapshots></pluginRepository><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>http://repo.spring.io/libs-milestone-local</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
<!-- spring_cloud_demo\pom.xml -->

3、SpringCloudGateWay 网关:入门案例–搭建环境–在父工程 spring_cloud_demo 下,创建子工程 eureka_service (子模块)。

3.1 创建 eureka_service 子工程(子模块)
	--> 右键 spring_cloud_demo 父工程--> Modules --> Maven --> Groupld : ( djh.it )Artifactld : ( eureka_service )Version : 1.0-SNAPSHOT--> Next --> Module name: ( eureka_service )Content root : ( \spring_cloud_demo\eureka_service )Module file location: ( \spring_cloud_demo\eureka_service )--> Finish
3.2 在子工程 eureka_service (子模块)中的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring_cloud_demo</artifactId><groupId>djh.it</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>eureka_service</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies></project>
<!-- spring_cloud_demo\eureka_service\pom.xml -->
3.3 在子工程 eureka_service (子模块)中,创建配置文件 application.yml 配置文件。
## spring_cloud_demo\eureka_service\src\main\resources\application.ymlserver:port: 9000  # 启动端口 命令行注入。spring:application:name: service-eureka  #spring应用名, # 注意 FeignClient 不支持名字带下划线eureka: # 配置 eureka_server
#  instance:
#    hostname: localhostclient:register-with-eureka: false  # 是否将自己注册到注册中心,不配置时,默认 true。 配置高可用时,须注销此行,或配置为 truefetch-registry: false  # 是否从 Eureka 中获取注册信息,不配置时,默认 true。 配置高可用时,须注销此行,或配置为 trueservice-url: # 配置暴露给 EurekaClient 的请求地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3.4 在子工程 eureka_service (子模块)中,创建 启动类 EurekaServerApplication.java
/***   spring_cloud_demo\eureka_service\src\main\java\djh\it\eureka\EurekaServerApplication.java**   2024-4-19  启动类 EurekaServerApplication.java*/
package djh.it.eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer  //激活 Eureka
public class EurekaServerApplication {//运行启动类,浏览器地址栏输入:localhost:9000  进行访问测试。public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}
}
3.5 在子工程 eureka_service (子模块)中,运行启动类,进行测试

浏览器地址栏输入:http://localhost:9000 输出界面如下:

在这里插入图片描述

4、SpringCloudGateWay 网关:入门案例–搭建环境–在父工程 spring_cloud_demo 下,创建子工程 product_service(子模块)

4.1 创建 生产者 子工程 product_service(子模块)
	--> 右键 spring_cloud_demo 父工程--> Modules --> Maven --> Groupld : ( djh.it )Artifactld : ( product_service )Version : 1.0-SNAPSHOT--> Next --> Module name: ( product_service )Content root : ( spring_cloud_demo\product_service )Module file location: ( spring_cloud_demo\product_service )--> Finish
4.2 在 生产者 子工程 product_service (子模块)中的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring_cloud_demo</artifactId><groupId>djh.it</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>product_service</artifactId><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><!--            <version>5.1.32</version>--><version>8.0.26</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- 引入 EurekaClient 依赖坐标 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies></project><!-- spring_cloud_demo\product_service\pom.xml -->
4.3 在 生产者 子工程 product_service (子模块)中,创建 商品实体类 Product.java
/***   spring_cloud_demo\product_service\src\main\java\djh\it\product\domain\Product.java**  2024-4-17 商品实体类 Product.java*/
package djh.it.product.domain;import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.math.BigDecimal;@Data
@Entity
@Table(name="tb_product")  //对应数据库中的数据表
public class Product {@Idprivate Long id;private String productName;private Integer status;private BigDecimal price;private String productDesc;private String caption;private Integer inventory;
}
4.4 在 生产者 子工程 product_service (子模块)中,创建 dao 持久层接口类 ProductDao.java
/***   spring_cloud_demo\product_service\src\main\java\djh\it\product\dao\ProductDao.java**  2024-4-17  dao 持久层接口 ProductDao.java*/
package djh.it.product.dao;import djh.it.product.domain.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;public interface ProductDaoextends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {}
4.5 在 生产者 子工程 product_service (子模块)中,创建 service 服务层 接口类 ProductService.java
/***   spring_cloud_demo\product_service\src\main\java\djh\it\product\service\ProductService.java**  2024-4-17  service 服务层 接口 ProductService.java*/
package djh.it.product.service;import djh.it.product.domain.Product;public interface ProductService {//根据id查询Product findById(Long id);//保存void save(Product product);//更新void update(Product product);//删除void delete(Long id);
}
4.6、在 生产者 子工程 product_service (子模块)中,创建 service 服务层 实现类 ProductServiceImpl.java
/***   spring_cloud_demo\product_service\src\main\java\djh\it\product\service\Impl\ProductServiceImpl.java**  2024-4-17  service 服务层 实现类*/
package djh.it.product.service.Impl;import djh.it.product.domain.Product;
import djh.it.product.dao.ProductDao;
import djh.it.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ProductServiceImpl implements ProductService {@Autowiredprivate ProductDao productDao;@Overridepublic Product findById(Long id) {return productDao.findById(id).get();}@Overridepublic void save(Product product) {productDao.save(product);}@Overridepublic void update(Product product) {productDao.save(product);}@Overridepublic void delete(Long id) {productDao.deleteById(id);}
}
4.7 在 生产者 子工程 product_service (子模块)中,创建 商品的 controller 类 ProductController.java
/***  C:\java-test\idea2019\spring_cloud_demo\product_service\src\main\java\djh\it\product\controller\ProductController.java**  2024-4-17 商品的 controller 类 ProductController.java*/
package djh.it.product.controller;import djh.it.product.domain.Product;
import djh.it.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/product")
public class ProductController {@Autowiredprivate ProductService productService;//获取服务器端口号@Value("${server.port}")private String port;//获取服务器IP地址@Value("${spring.cloud.client.ip-address}")   //springcloud 自动获取当前应用的IP地址private String ip;@RequestMapping(value = "/{id}", method = RequestMethod.GET)public Product findById(@PathVariable Long id){Product product = productService.findById(id);product.setProductName("访问的服务地址是:" + ip + " : " + port);return product;}@RequestMapping(value = "", method = RequestMethod.POST)public String save (@RequestBody Product product){productService.save(product);return "保存成功";}}
4.8 在 生产者 子工程 product_service (子模块)中,创建配置文件 application.yml
## C:\java-test\idea2019\spring_cloud_demo\product_service\src\main\resources\application.ymlserver:port: 9001  # 启动端口 命令行注入。
#  port: ${port:9001}  # 启动端口设置为动态传参,如果未传参数,默认端口为 9001
#  servlet:
#    context-path: /application1spring:application:name: service-product  #spring应用名, # 注意 FeignClient 不支持名字带下划线
#  main:
#    allow-bean-definition-overriding: true # SpringBoot2.1 需要设定。datasource:driver-class-name: com.mysql.jdbc.Driver  # mysql 驱动url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 12311jpa:database: MySQLshow-sql: trueopen-in-view: trueeureka:  # 配置 Eurekaclient:service-url:defaultZone: http://localhost:9000/eureka/
#      defaultZone: http://localhost:9000/eureka/,http://localhost:8000/eureka/  # 高可用,注册多个 eurekaserver 用 , 隔开。instance:prefer-ip-address: true  # 使用 ip 地址注册instance-id: ${spring.cloud.client.ip-address}:${server.port}  # 向注册中心注册服务的id(IP 地址)。lease-renewal-interval-in-seconds: 10  # 设置向注册中心每10秒发送一次心跳,告诉注册中心此服务没有岩机,此参数默认是30秒。lease-expiration-duration-in-seconds: 20  # 设置每20秒如果注册中心没收到此服务的心跳,就认为此服务岩机了,此参数默认是90秒。
4.9 在 生产者 子工程 product_service (子模块)中,创建 启动类 ProductApplication.java
/***   C:\java-test\idea2019\spring_cloud_demo\product_service\src\main\java\djh\it\product\ProductApplication.java**   2024-4-17  启动类 ProductApplication.java*/
package djh.it.product;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import java.io.Serializable;@SpringBootApplication
@EntityScan("djh.it.product.domain")
@EnableEurekaClient  //激活 EurekaClient, 同 @EnableDiscoveryClient 注解相同。
public class ProductApplication implements Serializable {//运行启动类,浏览器地址栏输入:localhost:9001/product/1  进行访问测试。public static void main(String[] args) {SpringApplication.run(ProductApplication.class, args);}
}
4.10 在 生产者 子工程 product_service (子模块)中,运行启动类,进行测试

浏览器地址栏输入:http://127.0.0.1:9001/product/1

输出 mysql 数据库的第一条记录:

在这里插入图片描述

5、SpringCloudGateWay 网关:入门案例–搭建环境–在父工程 spring_cloud_demo 下,创建子 order_service 工程(子模块)

5.1 创建 消费者 子工程 order_service(子模块)
	--> 右键 spring_cloud_demo 父工程--> Modules --> Maven --> Groupld : ( djh.it )Artifactld : ( order_service )Version : 1.0-SNAPSHOT--> Next --> Module name: ( order_service )Content root : ( \spring_cloud_demo\order_service )Module file location: ( \spring_cloud_demo\order_service )--> Finish
5.2 在消费者子工程(子模块) order_service 的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring_cloud_demo</artifactId><groupId>djh.it</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>order_service</artifactId><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><!--            <version>5.1.32</version>--><version>8.0.26</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- 引入 EurekaClient 依赖坐标 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- 引入 spring-retry 请求重试 依赖坐标 --><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency></dependencies></project>
<!-- spring_cloud_demo\order_service\pom.xml -->
5.3 在消费者子工程(子模块) order_service 中,创建配置文件 application.yml
## spring_cloud_demo\order_service\src\main\resources\application.ymlserver:port: 9002  # 启动端口 命令行注入。spring:application:name: service-order  #spring应用名, # 注意 FeignClient 不支持名字带下划线
#  main:
#    allow-bean-definition-overriding: true # SpringBoot2.1 需要设定。datasource:driver-class-name: com.mysql.jdbc.Driver  # mysql 驱动url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 12311jpa:database: MySQLshow-sql: trueopen-in-view: trueeureka:  # 配置 Eurekaclient:service-url:defaultZone: http://localhost:9000/eureka/instance:prefer-ip-address: true  # 使用 ip 地址注册
5.4 在消费者子工程(子模块) order_service 中,创建 商品实体类 Product.java
/***  spring_cloud_demo\order_service\src\main\java\djh\it\order\domain\Product.java**  2024-4-19 商品实体类 Product.java*/
package djh.it.order.domain;import lombok.Data;
import java.math.BigDecimal;@Data
public class Product {private Long id;private String productName;private Integer status;private BigDecimal price;private String productDesc;private String caption;private Integer inventory;
}
5.5 在消费者子工程(子模块) order_service 中,创建 controller 类 OrderController.java
/***    spring_cloud_demo\order_service\src\main\java\djh\it\order\controller\OrderController.java**  2024-4-19 订单的 controller 类 OrderController.java*/
package djh.it.order.controller;import djh.it.order.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;@RestController
@RequestMapping("/order")
public class OrderController {// 注入 restTemplate 对象@Autowiredprivate RestTemplate restTemplate;/***  使用 基于 ribbon 的形式调用远程微服务:*  1、使用 @LoadBalanced 注解 声明 RestTemplate*  2、使用服务名称 service-product 替换 IP 地址 。** @param id* @return*/@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)public Product findById(@PathVariable Long id){Product product = null;//product = restTemplate.getForObject("http://127.0.0.1:9001/product/1", Product.class);product = restTemplate.getForObject("http://service-product/product/1", Product.class);return product;}
}
5.6 在消费者子工程(子模块) order_service 中,创建 启动类 OrderApplication.java
/***   C:\java-test\idea2019\spring_cloud_demo\order_service\src\main\java\djh\it\order\OrderApplication.java**   2024-4-19  启动类 OrderApplication.java*/
package djh.it.order;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
@EntityScan("djh.it.order.domain")
@EnableEurekaClient  //激活 EurekaClient, 同 @EnableDiscoveryClient 注解相同。
public class OrderApplication {/***  使用 spring 提供的 RestTemplate 发送 http 请求到商品服务。*      1)创建 RestTemplate 对象交给容器管理。*      2)在使用的时候,调用其方法完成操作(getXX, postXX)。     **/@LoadBalanced  //使用 基于 ribbon 的形式调用远程微服务:使用 @LoadBalanced 注解 声明 RestTemplate@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}//运行启动类,浏览器地址栏输入:localhost:9002/order/buy/1  进行访问测试。public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}
5.7 运行启动类,进行测试

浏览器地址栏输入:http://127.0.0.1:9002/order/buy/1
输出 mysql 数据库的第一条记录:

在这里插入图片描述

6、SpringCloudGateWay 网关:入门案例–搭建环境–在父工程 spring_cloud_demo 下,创建子 api_gateway_service 工程(子模块)

6.1 创建 子工程 api_gateway_service(子模块)
	--> 右键 spring_cloud_demo 父工程--> Modules --> Maven --> Groupld : ( djh.it )Artifactld : ( api_gateway_service )Version : 1.0-SNAPSHOT--> Next --> Module name: ( api_gateway_service )Content root : ( \spring_cloud_demo\api_gateway_service )Module file location: ( \spring_cloud_demo\api_gateway_service )--> Finish
6.2 在子工程(子模块) api_gateway_service 的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring_cloud_demo</artifactId><groupId>djh.it</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>api_gateway_service</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency></dependencies></project>
<!-- spring_cloud_demo\api_gateway_service\pom.xml -->
6.3 在子工程(子模块) api_gateway_service 中,创建配置文件 application.yml
##  spring_cloud_demo\api_gateway_service\src\main\resources\application.ymlserver:port: 8088  # 启动端口 命令行注入。
spring:application:name: api-gateway-service  #spring应用名, # 注意 FeignClient 不支持名字带下划线# 配置 SpringCloudGateway 的路由cloud:gateway:routes:  # 配置路由,路由Id,路由到微服务的 uri, 断言(判断条件)- id: product-serviceuri: http://127.0.0.1:9001predicates:- Path=/product/**
6.4 在子工程(子模块) api_gateway_service 中,创建 启动类 GatewayServerApplication.java
/***   spring_cloud_demo\api_gateway_service\src\main\java\djh\it\gateway\GatewayServerApplication.java**   2024-5-7  启动类 GatewayServerApplication.java*/package djh.it.gateway;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class GatewayServerApplication {public static void main(String[] args) {SpringApplication.run(GatewayServerApplication.class, args);}
}

7、SpringCloudGateway 路由:gateway 依赖问题和内置断言条件介绍

7.1 启动 父工程 spring_cloud_demo 下 全部子项目的启动类,进行测试:

会发现在启动 子工程 api_gateway_service(子模块) 时,idea 控制台抛出异常,如下:

在这里插入图片描述

7.2 在各子模块( eureka_service, product_service, order_service )中的 pom.xml 文件中,导入 web 依赖坐标后,同时注销掉父工程 spring_cloud_demo 中 pom.xml 文件中的 web 依赖,重新运行各子模块启动类,进行测试。
        <!-- springcloudgateway 的内部是通过 netty + webflux 实现。webflux 实现和 springmvc 存在冲突,需要注销掉父工程中的 web 依赖,在各子模块中导入 web 依赖。--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
7.3 浏览器地址栏输入:http://localhost:8088 相当于 http://127.0.0.1:9001 所以:http://localhost:8088/product/1 相当于 http://127.0.0.1:9001/product/1

在这里插入图片描述

7.4 SpringCloudGateway 路由:gateway 内置断言条件介绍
##  spring_cloud_demo\api_gateway_service\src\main\resources\application.ymlserver:port: 8088  # 启动端口 命令行注入。
spring:application:name: api-gateway-service  #spring应用名, # 注意 FeignClient 不支持名字带下划线# 配置 SpringCloudGateway 的路由cloud:gateway:routes:  # 配置路由,路由Id,路由到微服务的 uri, 断言(判断条件)- id: product-service   # 保持唯一uri: http://127.0.0.1:9001   # 目标微服务请求地址predicates:   # 断言(判断条件)设置- Path=/product/**   # 路由条件 path : 路由路径匹配条件。 # 即:http://localhost:8088/product/1 相当于 http://127.0.0.1:9001/product/1
#            - After=xxxxxx  # 路由断言之后匹配。
#            - Before=xxxxxx  # 路由断言之前匹配。
#            - Between=xxxx.xxxx  # 路由断言之间匹配。
#            - Cookie=chocolate, ch.p  # 路由断言 cookie 匹配,此 predicate 匹配给定名称(chocolate)和正则表达式(ch.p)
#            - Header=X-Request-Id, /d+  # 路由断言 Header 匹配,header 名称匹配 X-Request-Id,且正则表达式匹配 /d+
#            - Host=**.somehost.org, **.anotherhost.org  # 路由断言 Host 匹配,匹配 host 主机列表, ** 代表可变参数。
#            - Method=GET  # 路由断言 Method 匹配,匹配的是请求的 HTTP 方法。
#            # - Path=/foo/{segment},/bar/{segment}  # 路由断言匹配,{segment} 为可变参数。
#            - Query=baz   # 或 Query=foo,ba.  # 路由断言 Query 匹配,将请求的参数 param(bax)进行匹配,也可以进行 regexp 正则表达式匹配(参数包含 foo, 并且 foo 的值匹配 ba.)。
#            - RemoteAddr=192.168.1.1/24  # 路由断言 RemoteAddr 匹配,将匹配 192.168.1.1~192.168.1.254 之间的 ip 地址,其中 24 为子网掩码位。

上一节关联链接请点击:
# 从浅入深 学习 SpringCloud 微服务架构(十)–zuul(2)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3019130.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

邮件群发系统的效率怎么样?如何评估性能?

邮件群发系统的使用方法&#xff1f;邮件群发工具的关键功能&#xff1f; 邮件群发系统已成为企业、组织及个人进行信息沟通的重要工具。然而&#xff0c;当我们谈论邮件群发系统的效率时&#xff0c;我们需要从多个维度来全面分析和评估。AokSend就来介绍一下。 邮件群发系统…

机器学习——4.案例: 简单线性回归求解

案例目的 寻找一个良好的函数表达式,该函数表达式能够很好的描述上面数据点的分布&#xff0c;即对上面数据点进行拟合。 求解逻辑步骤 使用Sklearn生成数据集定义线性模型定义损失函数定义优化器定义模型训练方法&#xff08;正向传播、计算损失、反向传播、梯度清空&#…

小项目“谈笑风生”测试报告

文章目录 一、项目介绍1.1项目背景1.2功能介绍 二、测试环境三、测试执行过程3.1功能测试3.1.1登录页面测试3.1.2注册页面测试3.1.3主页面测试 3.2界面自动化测试3.2.1登录模块测试3.2.2注册模块测试3.2.3展示各种信息模块测试3.2.34聊天消息传送模块测试 四、测试结论与建议 一…

vmware虚拟机内删除文件后宿主机空间不释放

问题描述 linux下&#xff0c;vmware内虚拟机删除文件&#xff0c;宿主机空间不释放&#xff0c;D盘快满了 解决方法 通过vmware-toolbox进行空间回收 安装 在虚拟机内操作 yum install -y open-vm-tools 清理 在虚拟机内操作 #查看磁盘的挂载点 sudo /usr/bin/vmware…

探索宇宙奥秘:太阳系运转的三维可视化之旅

在宇宙探索的伟大征途中&#xff0c;太阳系运转三维可视化技术为我们揭开了星辰大海的一角。通过图扑可视化技术&#xff0c;我们能够以前所未有的方式直观地体验和理解太阳及其周围行星的运动规律。这不仅是对于天文学家的一大帮助&#xff0c;也为广大天文爱好者和教育者提供…

如何理解GTX发送通道的用户接口?(高速收发器二)

前文讲解了高速收发器的QPLL及CPLL和差分时钟相关内容&#xff0c;如下图所示。本文就打开高速收发器通道的内部结构&#xff0c;进行简要讲解。 图21GTXE2_CHANNEL原始拓扑 收发器的内部框图如下所示&#xff0c;上半部分是发送通道&#xff0c;下半部分是接收通道&#xff0c…

ubuntu下pyinstaller打包多个.py文件

参考链接&#xff1a; https://blog.csdn.net/CholenMine/article/details/80964272 https://blog.csdn.net/BXD1314/article/details/125226289 前言 要把python项目打包成可执行程序运行&#xff0c;看了很多帖子&#xff0c;大多数博主都采用pyinstall 打包&#xff0c;但…

车间为什么选择蒸发式冷风机?

蒸发式冷风机具有以下特点&#xff1a; 节能环保&#xff1a;蒸发式冷风机不使用压缩机和化学制冷剂&#xff0c;而是通过水的蒸发来降低温度&#xff0c;因此它是无压缩机、无冷媒、无污染的环保型产品。降温效果显著&#xff1a;在较潮湿地区&#xff0c;它一般能达到5-9℃的…

苹果iPad M4:Console级别图形和AI强大功能

苹果iPad M4&#xff1a;Console级别图形和AI强大功能 Apple近日发布了最新的M4芯片&#xff0c;旨在为iPad Pro系列带来明显的性能提升和电池续航时间延长。在本篇报道中&#xff0c;我们将详细介绍M4芯片的特点、性能改进和为创意专业人士带来的影响。 M4芯片的强大功能 …

第二证券|1.73万亿“聪明钱”A股扫货买了什么?

跟着A股上市公司一季报披露收官&#xff0c;备受商场重视的险资、社保基金和QFII等各大组织持仓数据浮出水面。 Wind计算数据显现&#xff0c;719家A股上市公司的十大流通股股东有QFII身影&#xff0c;险资和社保基金分别现身754只和659只个股的前十大流通股股东&#xff0c;Q…

用户体验至上的Spring Boot博客系统

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

Linux/C++——线程池

什么是线程池 线程池其实就是一种多线程处理形式&#xff0c;处理过程中可以将任务添加到队列中&#xff0c;然后在创建线程后自动启动这些任务。 为什么要引入线程池 在单线程的场景中&#xff0c;如在服务端的服务中&#xff0c;要对多个客户端进行服务&#xff0c;单个线…

不得不聊的微服务Gateway

一、 什么是Gateway&#xff1f; 1.网关的由来 单体应用拆分成多个服务后&#xff0c;对外需要一个统一入口&#xff0c;解耦客户端与内部服务 2.网关的作用 Spring Cloud Gateway是Spring Cloud生态系统中的一员&#xff0c;它被设计用于处理所有微服务的入口流量。作为一…

志邦家居流程项目中心负责人郑瑶瑶受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 志邦家居股份有限公司流程项目中心负责人、战略及变革委员会秘书长郑瑶瑶女士受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“PMO在制造企业的标准化建设之路”。大会将于6月29-30日在北京举办&#xff0c;敬请关注&…

社区智能奶柜:创业新机遇

社区智能奶柜&#xff1a;创业新机遇 在追求高质量生活的今天&#xff0c;健康食品成为大众焦点。社区智能奶柜适时登台&#xff0c;革新了居民获取新鲜牛奶的传统模式&#xff0c;为创业者开辟了一片蓝海市场。 一、新兴创业蓝海&#xff1a;牛奶随享站 日常膳食中&#xf…

【系统架构师】-UML-用例图(Use Case)

1、概述 用于表示系统功能需求&#xff0c;以及应用程序与用户或者与其他应用程序之间的交互关系。 2、组成 参与者&#xff08;Actors&#xff09;&#xff1a;与系统交互的用户或其他系统。用一个人形图标表示。用例&#xff08;Use Cases&#xff09;&#xff1a;系统需要…

sql查询数据语句

select * from 表名 where 列名 某个数据名字 查询某个表名中的某列是否有某个数据

孩子咳嗽,积食?可以试试宋乐冬医生分享的几个缓解方法~

最近气温变化大忽冷忽热&#xff0c;多变的天气容易引发儿童疾病。 不少妈妈也在后台咨询&#xff0c;想要学习一下常用的小儿推拿&#xff0c;在孩子身体出现轻微不适时&#xff0c;能够给孩子做做小儿推拿来辅助治疗&#xff0c;缓解不适恢复健康。 今天我们就一起学习一下&a…

视频剪辑图文实例:一键操作,轻松实现视频批量片头片尾减时

视频剪辑是现代媒体制作中不可或缺的一环&#xff0c;而批量处理视频更是许多专业人士和爱好者的常见需求。在剪辑过程中&#xff0c;调整视频的片头片尾时长可以显著提升视频的质量和观感。本文将通过图文实例的方式&#xff0c;向您展示如何一键操作&#xff0c;轻松实现视频…

Debian——安装syzkaller——2024

系统:Debian 远程连接——我是不想安装tools没有办法复制黏贴,所以远程,根据个人情况选择是否远程连接 就是说使用Windows自带的远程mstsc,使用的不是ssh22端口,是TCP 3389端口 mkdir debian cd debian 二:安装go编译器 打开终端。使用wget命令从官方网站或可信的镜像…