微服务案例搭建

目录

一、案例搭建

1.数据库表

2.服务模块

二、具体代码实现如下:

[(1) 首先是大体框架为:](#(1) 首先是大体框架为:)

(2)父模块中的pom文件配置

(3)shop_common模块,这个模块里面只需要配置pom.xml,与实体类

(4)在shop_product、shop_order、shop_user子模块中导入公共子模块common的坐标

(4.1)shop_product的pom.xml

(4.2)shop_order的pom.xml

(4.3)shop_user的pom.xml

三、服务调⽤

1.RestTemplate介绍

2.RestTemplate⽅法介绍

3.通过RestTemplate调⽤微服务

(1)shop_order的控制层

[(2)shop_order的 service层:](#(2)shop_order的 service层:)

[(3)shop_order的 OrderMappper数据访问层代码:](#(3)shop_order的 OrderMappper数据访问层代码:)

[(4)shop_order的 测试类主入口代码:](#(4)shop_order的 测试类主入口代码:)

[(5)shop_order的 测试类主入口代码:](#(5)shop_order的 测试类主入口代码:)


一、案例搭建

使⽤微服务架构的分布式系统,微服务之间通过⽹络通信。我们通过服务提供者与服务消费者来描述微服 务间的调⽤关系。

服务提供者:服务的被调⽤⽅,提供调⽤接⼝的⼀⽅

服务消费者:服务的调⽤⽅,依赖于其他服务的⼀⽅

我们以电商系统中常⻅的⽤户下单为例,⽤户向订单微服务发起⼀个购买的请求。在进⾏保存订单之前 需要调⽤商品微服务查询当前商品库存,单价等信息。在这种场景下,订单微服务就是⼀个服务消费 者,商品微服务就是⼀个服务提供者。

1.数据库表

shop_order订单表

shop_product商品表

shop_user⽤户表

2.服务模块

创建公共⽗模块springcloud_alibaba

创建公共模块 shop_common ,⽤于存放公共的实体类和⼯具类

创建订单微服务模块 shop_order 端⼝809X

创建商品微服务模块 shop_product 端⼝808X

创建⽤户微服务模块 shop_user 端⼝807X


二、具体代码实现如下

(1) 首先是大体框架为:

其中common用于存在实体类对象,order用于创建订单,product用于操作产品信息,user用于操作用户信息。

(2)父模块中的pom文件配置
XML 复制代码
   <!-- 项目基本信息 -->
    <groupId>com.zad</groupId>
    <artifactId>springcloud_alibaba</artifactId>
    <version>1.0-SNAPSHOT</version>

这里定义了项目的基本信息,包括groupId(组织标识符)、artifactId(项目标识符)、和version(版本号)。这些信息唯一标识了该Maven项目。

XML 复制代码
    <!-- pom:父文件 -->
    <packaging>pom</packaging>

这个项目打包类型为pom,意味着它是一个聚合项目或父项目,用来管理多个子模块。

XML 复制代码
    <!-- 父项目的子模块 -->
    <modules>
        <module>shop_order</module>
        <module>shop_product</module>
        <module>shop_user</module>
        <module>shop_commen</module>
    </modules>

定义了该父项目的四个子模块。

XML 复制代码
    <!-- 依赖版本的锁定 -->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        <spring-cloud-alibaba.version>2.1.1.RELEASE</spring-cloud-alibaba.version>
    </properties>

这里定义了一些属性,如Java版本、编码格式,以及Spring Cloud和Spring Cloud Alibaba的版本。这些属性可以在整个POM文件中复用,方便管理和升级。

XML 复制代码
    <!--
        dependencyManagement所包含的坐标,子项目不会直接继承,需要声明才可继承
         -->    
    <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-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

在dependencyManagement部分定义了依赖管理。这里指定了Spring Cloud和Spring Cloud Alibaba的依赖项及其版本。这些依赖项不会自动应用到子项目中,子项目需要显式声明才能继承

(3)shop_common模块,这个模块里面只需要配置pom.xml,与实体类

pom.xml

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>springcloud_alibaba</artifactId>
        <groupId>com.zad</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shop_commen</artifactId>
    <!-- 依赖 -->
    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>springcloud_alibaba</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

在domain包下创建了三个实体类用于创建存储订单、产品、用户,这里只展示订单的代码,其余代码均相同逻辑:

XML 复制代码
@TableName("shop_order")
@Data
public class Order {
    @TableId(value = "oid",type = IdType.AUTO)
    private Long oid;//订单id

    //用户
    @TableField("uid")
    private Integer uid;//用户id
    @TableField("username")
    private String username;//用户名

    //商品
    @TableField("pid")
    private Integer pid;//商品id
    @TableField("pname")
    private String pname;//商品名称
    @TableField("pprice")
    private Double pprice;//商品单价

    //数量
    @TableField("number")
    private Integer number;//购买数量
}

通过@TableName映射shop_order数据库,其余的都是成员变量的创建和映射。

(4)在shop_product、shop_order、shop_user子模块中导入公共子模块common的坐标
XML 复制代码
        <!-- shop-common -->
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>shop_commen</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
(4.1)shop_product的pom.xml
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>springcloud_alibaba</artifactId>
        <groupId>com.zad</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shop_product</artifactId>
    <dependencies>
        <!-- springboot-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- shop-common -->
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>shop_commen</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>springcloud_alibaba</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
(4.2)shop_order的pom.xml
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>springcloud_alibaba</artifactId>
        <groupId>com.zad</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shop_order</artifactId>

    <dependencies>
        <!-- springboot-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- shop-common -->
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>shop_commen</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>springcloud_alibaba</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
(4.3)shop_user的pom.xml
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>springcloud_alibaba</artifactId>
        <groupId>com.zad</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shop_user</artifactId>
    <dependencies>
        <!-- springboot-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- shop-common -->
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>shop_commen</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.zad</groupId>
            <artifactId>springcloud_alibaba</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

</project>

三、服务调⽤

前⽂已经编写了三个基础的微服务,在⽤户下单时需要调⽤商品微服务获取商品数据。那应该怎么做 呢?总⼈皆知商品微服务提供了供⼈调⽤的HTTP接⼝。所以可以再下定单的时候使⽤http请求的相关⼯ 具类完成,如常⻅的HttpClient ,OkHttp,当然也可以使⽤Spring提供的RestTemplate

1.RestTemplate介绍

Spring框架提供的RestTemplate类可⽤于在应⽤中调⽤rest服务,它简化了与http服务的通信⽅式,统 ⼀了RESTful的标准,封装了http链接, 我们只需要传⼊url及返回值类型即可。相较于之前常⽤的 HttpClient ,RestTemplate是⼀种更优雅的调⽤RESTful服务的⽅式。

在Spring应⽤程序中访问第三⽅REST服务与使⽤Spring RestTemplate类有关。 RestTemplate类的设 计 原则与许多其他Spring 模板类(例如JdbcTemplate、JmsTemplate)相同,为执⾏复杂任务提供了⼀ 种具有默认⾏为的简化⽅法。

RestTemplate默认依赖JDK提供http连接的能⼒(HttpURLConnection),如果有需要的话也可以通过 setRequestFactory⽅法替换为例如 Apache HttpComponents、 Netty或OkHttp等其它HTTP library。 考虑到RestTemplate类是为调⽤REST服务⽽设计的,因此它的主要⽅法与REST的基础紧密相连就不⾜ 为奇了,后者是HTTP协议的⽅法:HEAD、GET、 POST、 PUT、 DELETE和OPTIONS。例如, RestTemplate类具有headForHeaders()、getForObject()、 postForObject()、 put()和delete()等⽅法。

2.RestTemplate⽅法介绍

分为三组:

  • getForObject --- optionsForAllow 分为一组,这类方法是常规的 Rest API(GET、POST、DELETE 等)方法调用;
  • exchange:接收一个 RequestEntity 参数,可以自己设置 HTTP method,URL,headers 和 body,返回 ResponseEntity;
  • execute:通过 callback 接口,可以对请求和返回做更加全面的自定义控制。
3.通过RestTemplate调⽤微服务
(1)shop_order的控制层
java 复制代码
@RestController
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IOrderService orderService;

    //下单
    @RequestMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {

        //调用商品微服务,查询商品信息
        Product product =
                restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class);

        //下单(创建订单)
        Order order = new Order();
        order.setUid(1);
        order.setUsername("测试用户");
        order.setPid(pid);
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        orderService.createOrder(order);
        return order;
    }
}

其中RestTemplate对象是用于在服务之间发起 HTTP 请求的模板类。它封装了 HTTP 请求和响应的处理逻辑,提供了一组便捷的方法来与外部 RESTful 服务进行交互。

通过.getForObject方法,调用商品微服务,通过 HTTP GET 请求调用商品服务的接口获取商品信息。

然后再创建order对象通过mybatis-puls提供的接口来调用创建订单的方法:

(2)shop_order的 service层:

接口:

java 复制代码
public interface IOrderService extends IService<Order> {

    //创建订单
    void createOrder(Order order);
}

IService 是 MyBatis-Plus 提供的一个通用服务接口,提供了许多 CRUD(创建、读取、更新、删除)操作的默认实现方法。继承了 IService<Order> 后,IOrderService 接口就拥有了这些通用的 CRUD 功能,比如 save、remove、update、getById 等。

实现类:

java 复制代码
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired(required = false)
    private OrderMapper orderMapper;
    @Override
    public void createOrder(Order order) {
        orderMapper.insert(order);
    }
}

这个继承了ServiceImpl抽象类,是 MyBatis-Plus 提供的一个抽象类,实现了IService接口的大部分常用方法,又实现了IOrderService的接口,通过继承 ServiceImpl,OrderServiceImpl 类自动获得了所有 CRUD 方法的实现,无需手动编写这些基本操作的代码。

(3)shop_order的 OrderMappper数据访问层代码:
java 复制代码
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}

BaseMapper 是 MyBatis-Plus 提供的一个通用 Mapper 接口,已经实现了基本的 CRUD(创建、读取、更新、删除)操作。

(4)shop_order的 测试类主入口代码:
java 复制代码
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class);
    }
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

因为控制器需要用到restTemplate,所以在测试类中定义了一个RestTemplate的bean。

(5)shop_order的 测试类主入口代码:
java 复制代码
server:
  port: 8091
spring:
  application:
    name: service_order
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///shop?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: password

其中server:port代表配置Spring Boot 应用的服务器端口号。

spring: application: name: service-order配置应用程序的名称为 service-order。这个名称在微服务架构中很重要,通常用于服务发现、注册中心(如 Nacos 或 Eureka)等场景。

后面的是配置数据库和jdbc的连接。


这里我就省略shop_product和shop_user的代码了,同时执行三个模块,通过shop_order中的restTemplate去调用地址实现获取商品信息和用户信息,最后进行下单操作。

执行结果

在数据库中也可以查询到增加的订单信息。

相关推荐
岁忧2 分钟前
(LeetCode 每日一题) 1865. 找出和为指定值的下标对 (哈希表)
java·c++·算法·leetcode·go·散列表
YuTaoShao6 分钟前
【LeetCode 热题 100】240. 搜索二维矩阵 II——排除法
java·算法·leetcode
亲爱的非洲野猪17 分钟前
Kafka “假死“现象深度解析与解决方案
分布式·kafka
虾条_花吹雪22 分钟前
2、Connecting to Kafka
分布式·ai·kafka
考虑考虑1 小时前
JDK9中的dropWhile
java·后端·java ee
想躺平的咸鱼干1 小时前
Volatile解决指令重排和单例模式
java·开发语言·单例模式·线程·并发编程
hqxstudying2 小时前
java依赖注入方法
java·spring·log4j·ioc·依赖
·云扬·2 小时前
【Java源码阅读系列37】深度解读Java BufferedReader 源码
java·开发语言
Edingbrugh.南空2 小时前
Hadoop高可用集群搭建
大数据·hadoop·分布式
Bug退退退1233 小时前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq