案例
约 1273 字大约 4 分钟
2025-04-02
1. SpringCloud环境搭建
1.1 前期准备
【技术选型】
java:jdk17+
maven:3.6.3+
boot: 3.2.3
cloud: 2023.0.0
cloud alibaba: 2023.0.0.0-RC1
mysql: 8.0+
【环境准备】
1. 安装jdk17+、maven3.6.3+、mysql8.0+
2. 配置maven仓库
3. 配置mysql数据库
【项目结构】
# maven项目主模块:
syh-mall 父工程
# springcloud项目子模块
mall-pms - 商品微服务 【端口: 808x】
mall-oms - 订单微服务 【端口: 809x】
【项目需求】 在微服务架构中,最常见的场景就是微服务之间的相互调用。我们以电商系统中常见的用户下单为例来演示微服务的调用:客户向订单微服务发起一个下单的请求,在进行保存订单之前需要调用商品微服务查询商品的信息。
我们一般把服务的主动调用方称为服务消费者,把服务的被调用方称为服务提供者。在这种场景下,订单微服务就是一个服务消费者, 商品微服务就是一个服务提供者。
1.2 项目搭建
1.2.1 创建父工程 syh-mall
添加依赖
<?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>com.syh</groupId>
<artifactId>springcloud-shop</artifactId>
<version>1.0-SNAPSHOT</version>
<!--打包方式,父工程必须为pom-->
<packaging>pom</packaging>
<!--SpringBoot父工程-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--版本控制-->
<!-- spring cloud & alibaba -->
<spring-cloud.version>2023.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.0.0-RC1</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!--Spring Cloud & Alibaba -->
<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-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
或者
<?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>com.syh</groupId>
<artifactId>springcloud-shop</artifactId>
<version>1.0-SNAPSHOT</version>
<!--打包方式,父工程必须为pom-->
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--版本控制-->
<!-- SpringBoot -->
<spring-boot.version>3.2.3</spring-boot.version>
<!-- spring cloud & alibaba -->
<spring-cloud.version>2023.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.0.0-RC1</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!--Spring Boot & Spring Cloud & Alibaba -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
1.2.2 创建子工程 mall-pms
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
application.yml
server:
port: 8090
spring:
application:
name: syh-product
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
action接口
// 根据订单ID查看产品集合
@RequestMapping("/get/{oid}")
public List<Product> getAllProductsByOrderId(
@PathVariable("oid") Long orderId) {
System.out.println("订单ID:"+orderId);
return Arrays.asList(
new Product().setId(1L).setName("Product1")
.setStock(101).setDescription("This is a product1"),
new Product().setId(2L).setName("Product2")
.setStock(101).setDescription("This is a product1"),
new Product().setId(3L).setName("Product3")
.setStock(101).setDescription("This is a product1")
);
}
1.2.3 创建子工程 mall-oms
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
application.yml
server:
port: 8080
spring:
application:
name: syh-order
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
API接口
@GetMapping("/get/{id}")
public Order getOrderById(@PathVariable("id") Long id) {
//
Order order = new Order();
order.setNo("123456");
order.setName("测试订单");
order.setDesc("测试订单描述");
order.setDate("2021-01-01");
order.setStatus("待支付");
order.setAmount("100.00");
// 调用syh-product服务获取订单商品信息
// order.setProducts(products);
return order;
}
1.2.3 服务接口调用
- RestTemplate 注入RestTemplate对象
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
远程接口调用
@RequestMapping("/get/{id}")
public String test(@PathVariable("id") int id){
@GetMapping("/get/{id}")
public Order getOrderById(@PathVariable("id") Long id) {
//
Order order = new Order();
order.setNo("123456");
order.setName("测试订单");
order.setDesc("测试订单描述");
order.setDate("2021-01-01");
order.setStatus("待支付");
order.setAmount("100.00");
// 调用syh-product服务获取订单商品信息
String url = "http://localhost:8090/product/get/"+id;
List<Product> products = restTemplate.getForObject(url, List.class);
order.setProducts(products);
return order;
}
问题: 将来服务越来越多,订单服务一台机子也撑不下来,同时我们总是依靠ip加端口去寻找服务也不太合适,如果每一个服务都有一个名字就好了。 还记得dns吗? 我们上网并不需要记住ip地址,访问的时候根据域名找一下ip不就行了,只要域名不变,ip随便变都没有影响 所以在微服务里出现的一个名词,叫注册中心
1.2.4 测试负载均衡
- 复制多个产品服务
选中要复制的服务,按ctrl+d 添加端口号:
- 在订单服务添加负载均衡依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
- 给RestTemplate添加负载均衡注解
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
- 接口调用不能指定IP+端口了,需要改成服务名
@RequestMapping("/get/{id}")
public String test(@PathVariable("id") int id){
@GetMapping("/get/{id}")
public Order getOrderById(@PathVariable("id") Long id) {
//
Order order = new Order();
order.setNo("123456");
order.setName("测试订单");
order.setDesc("测试订单描述");
order.setDate("2021-01-01");
order.setStatus("待支付");
order.setAmount("100.00");
// 调用syh-product服务获取订单商品信息
//String url = "http://localhost:8090/product/get/"+id;
String url = "http://syh-product/product/get/"+id;
List<Product> products = restTemplate.getForObject(url, List.class);
order.setProducts(products);
return order;
}