微服务基础,分布式核心,常见微服务矿建,SpringCloud概述,搭建SpringCloud微服务项目详细步骤,含源代码

news2024/7/6 18:58:28

微服务基础

系统架构的演变

随着会联网的发展,网站应用的规模不断扩大,常规的应用架构已经无法应对,分布式服务架构以及微服务架构势在必行,必须一个治理系统确保架构有条不紊的演进

单体应用框架

Web应用程序发展的早期,大部分Web工程(包括前端页面,web层代码,service层代码,dao层代码)是将所有的功能模块打包到一起并发昂在一个web容器中运行

在这里插入图片描述

比如搭建一个电商系统;客户下订单,商品展示,用户管理,这种将所有功能都部署到一个web容易中运行的系统就叫单体架构

优点:

  • 所有的功能都能集成在一个项目工程中
  • 项目架构简单,前期开发成本低,周期短,小型项目首选

缺点:

  • 全部功能集成在一个工程中,对于大型项目不易开发,扩展及维护
  • 系统性能扩展只能通过扩展集群节点,成本高,有瓶颈
  • 技术栈受限制(单体架构必须采用相同的技术栈)

垂直应用架构

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率

在这里插入图片描述

优点:

  • 项目架构简单,前期开发成本低,周期短,小型项目的首选
  • 通过垂直拆分,原来的单体项目不至于无限扩大
  • 不同的项目可采用不同的技术

缺点:

  • 全部功能继承在一个工程中,对于大型项目不易开发,扩展及维护
  • 系统性能扩展只能通过扩展集群节点,成本高,有瓶颈

分布式SOA架构

什么是SOA

SOA全称为Service-Oriented Architecture,即面向服务的架构。它可以根据需求通过网络对松散耦合的粗颗粒应用组件(服务)进行分布式部署,组合和使用。一个服务通常以堵路的形式存在于操作系统进程中。站在功能的角度,把业务逻辑抽象成可复用,可组装的服务,通过服务的编排实现业务的快速再生,目的:把原先固有的业务功能转变为通用的业务服务,实现业务逻辑的快速服用

通过上面的描述可以发现SOA有如下几个特点:分布式、可重用、扩展灵活、松耦合

SOA架构

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的相应多变的市场需求

在这里插入图片描述

优点:

  • 抽取公共的功能为服务,提高开发效率
  • 对不同的服务进行集群化部署解决系统压力
  • 基于ESB/DUBBO减少系统耦合

缺点:

  • 抽取服务的粒度较大
  • 服务提供方与调用方接口耦合度较高

微服务架构

在这里插入图片描述

优点:

  • 通过服务的原子化拆分,以及微服务的独立打包,部署和升级,小团队的交付周期将缩短,运维成本也将大幅度下降
  • 微服务遵循单一原则。微服务之间采用Restful等轻量协议传输

缺点:

  • 微服务过多,服务治理成本高,不利于系统维护
  • 分布式系统开发的技术成本高(容错,分布式事务等)

SOA与微服务之间的关系

SOA架构,“面向服务的架构”:它是一种设计方法,其中包含多个服务,服务之间通过相互依赖最终提供一系列的功能。一个服务通常以独立的形式存在于操作系统的进程中。各种服务之间通过网络调用

**微服务架构:**其实和SOA架构类似,微服务实在SOA上做的生化,微服务架构强调的一个重点是业务需要彻底的组件化和服务化,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和继承

功能SOA微服务
组件大小大块业务逻辑单独任务或小块业务逻辑
耦合通常松耦合总是松耦合
公司架构任何类型小型,专注于功能交叉团队
管理着重中央管理着重分散管理
目标确保应用能够交互操作执行新功能,快速拓展开发团队

总结:单体应用架构---->垂直应用架构---->分布式架构---->SOA架构---->微服务架构,当然还有悄然兴起的Service Mesh(服务网格化)

分布式核心

分布式中的远程调用

在微服务架构中,通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分: 序列化和通信协议。常见的序列化协议包括json、xml、 hession、 protobuf、thrift、text、 bytes等,目前主流的远程调用技术有基于HTTP的RESTful接口以及基于TCP的RPC协议。

RESTful接口

REST,即Representational State Transfer的锁芯,如果一个架构复合REST原则,就称它为RESTful架构

资源(Resources)

所谓“资源”,就是网络上的一个实体,或者说是网络上的一个具体信息.它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在.你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符.REST的名称“表现层状态转化”中,省略了主语.
“表现层”其实指的是“资源”(Resources)的“表现层”

表层层(Representation)

“资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表 现层”(Representation)。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格 式表现,甚至可以采用二进制格式,图片可以用JPG格式表现,也可以用PNG格式表现。 URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的”.html"后缀名是不必要的,因为这个后缀名表示 格式属于"表现层”范畴,而URI应该只代表"资源”的位置。

状态转化(State Transfer)

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化”( State Transfer )。 客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT. DELETE。它们分别对应四种基本提作: GET用来获取资源,POST用来新建资源(也可以用于更新资源) ,PUT用来更新资源,DELETE用来删除资源

RESTful架构总结:

  • 每一个URI代表一种资源
  • 客户端和服务器之间,传递这种资源的某种表现层
  • 客户端用过四个HTTP动词,对服务器端资源进行操作,实现“表现层状态转化”

RPC协议

RPC(Remote Procedure Call)一种进程之间通信方式。允许像调用本地服务一样调用远程服务。RPC框架的主要目标就是让远程服务调用更简单、透明。 RPC框架负责屏底层的传输方式,(TCP或者UDP)序列化方式(XMLJSON/二进制)和通信细节。开发人员在使用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。

在这里插入图片描述

区别与联系

比较项RESTfulRPC
通讯协议HTTP一般使用TCP
性能略低较高
灵活度
应用微服务架构SOA架构
  1. HTTP相对更规范,更标准,更通用,无论哪种语言都支持http协议。如果你是对外开放API,例如开放平台,外部的编程语言多种多样,你无法拒绝对每种语言的支持,现在开源中间件,基本最先支持 的几个协议都包含RESTful
  2. RPC 框架作为架构微服务化的基础组件,它能大大降低架构微服务化的成本,提高调用方与服务提 供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节。让调用方感觉就像调用本地函数一样 调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务

分布式中的CAP原理

现如今,对于多数大型互联网应用,分布式系统 (distributed system)正变得越来越重要。分布式系统的最大难点,就是各个节点的状态如何同步。CAP 定理是这方面的基本定理,也是理解分布式系统的起点CAP理论由 Eric Brewer 在ACM研讨会上提出,而后CAP被奉为分布式领域的重要理论。分布式系统的 CAP理论,首先把分布式系统中的三个特性进行了如下归纳:

在这里插入图片描述

Consistency(一致性):数据一致更新,所有数据的变化都是同步的

Availability(可用性):在集群中一部分节点故障后,集群整体是否还能响应客户端的去写请求

Partition tolerance(分区容忍性):某个节点的故障,并不影响整个系统的运行通过学习CAP理论,我们得知任何分布式系统只可同时满足二点,没法三者兼顾,既然一个分布 式系统无法同时满足一致性、可用性、分区容错性三个特点,所以我们就需要抛弃一样:

在这里插入图片描述

选择说明
CA放弃分区容错性,加强一致性和可用性,其实就是传统的关系型数据库的选择
AP放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,例如很多NoSQL系统就是如此
CP放弃可用性,追求一致性和分区错误性,基本不会选择,网络问题会直接让整个系统不可用

常见的微服务框架

  • SpringCloud

    SpringCloud:一系列架的有序集合它利用prng Bo0t的开发便利生地简化了分布式系统基 设施的开发,如服务发现注册、面置中心、消息总线、负载均、断路器、数居监等,都以用spring Boot的开发风格做到一键白动本部。 Sprng (loud并没有重复造轮子,它只是将前各家 司开发的成熟、经得起实际考的服务架组合起来,通过Soring Bot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

  • ServiceComb

    Apache ServiceComb:是业第个Apache微服务级项目,是一个开源微服务解方案 致力于帮助企业、用户和开发者将企业应用轻松微服务化上云,并实现对微服务应用的高效运维管理其提供一站式开源微服务解决方案,融合SDK框架级、 侵入ServiceMesh场景并支持多语言。

  • ZeioC ICE

    ZeioC IceGrid:是Zero(公司的本作,继承了CORBA的血统,是新一的面向对象的分布式系统中间件,作为一种微服务架构,它基于RPC框架发展而来,具有良好的性能与分布土能力

SpringCloud概述

微服务中的相关概念

服务注册与发现

服务注册

​ 服务实例将自身服务信息注册到注册中心。这部分服务信息包括服务所在主机P和提供服务 的Pot,以及暴露服务自身状态以及访问协议等信息.

服务发现

​ 服务实例请求注册中心获取所依赖服务信息。服务实例通过注册中心,获取到注册到其中的 服务实例的信息,通过这些信息去请求它们提供的服务

负载均衡

​ 负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应 用、数据库或其他服务的性能和可靠性

熔断

熔断这一概来源于电子工程中的断路器Crcut breake),在互联网系统中,当下游服务因访可压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断

链路追踪

随着微服务架沟的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务,互联网应用沟建在不同的软件莫快集上,这些软中模块,有可能是由不同的团队开发、编程语言 来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要对一次请求涉及的多个 服务链路进行日志记录,性能监控即链路追踪

API网关

随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现

  • 客户端需要调用不同的url地址,增加难度
  • 再一定的场景下,存在跨域请求的问题
  • 每个微服务都需要进行单独的身份认证

针对这些问题,API网关顺势而生
API网关:直面意思是将所有API调用统一接入到API网关层,由网关层统一接入和输出。一个网关的基本 功能有: 统一接入、
安全防护、协议适配、流量管控、长短链接支持、容错能力。有了网关之后,各个 API服务提供团队可以专注于自己的的业务逻辑处理,而API网关更专注于安全、流量、路由等问题。

SpringCloud的介绍

在这里插入图片描述

SpringCloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基 础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boo的开发风格做到一键言动高署。Sprmg Cloud并没有重复制造轮子,只是将前各家 公司开发的比熟、经得起实际考验的服务实合起来,通Sporng Boot风格进行
封装屏蔽掉 了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

SpringCloud的架构

核心组件

Spring loud的本质是在 Spring Boot 的基上,增加了一服务相关的现范,并对应用上下文进行了能增。既然 Spring Cloud 是现范,那就需要去实现,目前Sorin Cloud 规范已有Spring官方,Spring Cloud Netlix,Spring Cloud Alibaba等实现。通过组件化的方式,Spring Cloud将这些实现整合到一起构成全家桶式的微服务技术栈

Spring Cloud Netfilx组件

组件名称作用
Eureka服务注册中心
Ribbon客户端负载均衡
Feign声明式服务调用
Hystrix客户端容错保护
ZuulAPI服务网关

Spring Cloud Alibaba组件

组件名称作用
Nacos服务注册中心
Sentinel客户端容错保护

Spring Cloud原生及其他组件

组件名称作用
Consul服务注册中心
Config分布式配置中心
GatewayAPI服务网关
Slenuth/Zipkin分布式链路追踪

案例搭建

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

服务提供者: 服务的被调用方,提供调用接口的一方
服务消费者: 服务的调用方,依赖于其他服务的一方
我们以电商系统中常见的用产下单为例,用户向订单做服务发起一个购买的请求,在进行保存订单之前 需要调用商品微服务查询当前商车存,单价等信息。在这种场景下,订单微服务就是一个服务消费者,商品微服务就是一个服务提供者

在这里插入图片描述

实现步骤

  1. 建立数据库

    shop_order订单表

    shop_product商品表

    shop_user用户表

  2. 服务模块,项目搭建

    • 创建公共父模块

    • 创建公共模块shop_common,用于存放公共的实体类和工具类

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

    • 创建商品微服务模块shop_product 端口号808X

    • 创建用户服务模块shop_user 端口号807X

  3. 服务调用

    已经编写的三个基础的微服务,在用户下单时需要调用商品微服务获取商品信息。商品微服务提供了供人调用的HTTP接口,所以可以在下订单的时候使用HTTP请求的相关工具类完成,如常见的HttpClient,OkHtto,当然也可以使用Spring提供的RestTemplate

RestTemplate介绍

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

在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring 模板类(例如dbcTemplate、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()、 put0和delete()等方法

RestTemplate方法介绍

在这里插入图片描述

通过RestTemplate调用微服务

  1. 在shop_order工程中配置RestTemplate

    @Bean
    public RestTemplate getRestTemplate(){
    	return new RestTemplate();
    }
    
  2. 通过restTemplate调用商品微服务

    resTemplate.getForObject("http://localhost:8081/product/1",Product.class);
    

硬编码存在的问题

至此已经可以通过RestTemplate调用商品微服务的RESTFul API接口:但是我们把提供者的网络地址
(ip,端口)等硬编码到了代码中,这种做法存在许多问题:

  • 应用场景局限
  • 无法动态调整

就需要通过注册中心动态的对服务注册和服务发现

代码实现

项目目录结构:

在这里插入图片描述

  • 创建公共父模块
  1. 新建一个SpringBoot项目

  2. 删除src目录,只保存.idea文件夹和pom.xml配置文件

  3. 编写pom文件

    <?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.dong</groupId>
        <artifactId>springCloud_test</artifactId>
        <version>1.0-SNAPSHOT</version>
        <!--pom:打包的形式(三种:jar,war,pom)-->
        <packaging>pom</packaging>
    
        <!--父项目的子模块-->
        <modules>
            <module>shop_common</module>
            <module>shop_order</module>
            <module>shop_product</module>
            <module>shop_user</module>
        </modules>
    
        <!--父工程-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
        </parent>
    
        <!--依赖版本的锁定-->
        <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>
    
        <!-- 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>
    </project>
    
  • 创建公共模块shop_common,用于存放公共的实体类和工具类
  1. 右键工程,新建模块,选择maven项目(也可以选择SpringBoot项目,需要删除多余的文件)新建项目名就是父项目的子模块中配置的名字,所以此模块叫shop_common

  2. 编写shop_common的pom文件

    <?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_test</artifactId>
            <groupId>com.dong</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    		
      	<!-- 此模块信息 -->
        <groupId>com.dong</groupId>
        <artifactId>shop_common</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <!--依赖-->
        <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>
        </dependencies>
    </project>
    
  3. 此模块是公共类,存放实体类和工具类

    Order

    @TableName(value = "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;//购买数量
    }
    

    User

    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.Data;
    
    @TableName(value = "shop_user")
    @Data
    public class User {
        @TableId(value = "uid",type = IdType.AUTO)
        private Integer uid;//主键
        @TableField("username")
        private String username;//用户名
        @TableField("password")
        private String password;//密码
        @TableField("telephone")
        private String telephone;//手机号
    }
    

    Product

    @TableName(value = "shop_product")
    @Data
    public class Product {
        @TableId(value = "pid",type = IdType.AUTO)
        private Integer pid;//主键
        @TableField("pname")
        private String pname;//商品名称
        @TableField("pprice")
        private Double pprice;//商品价格
        @TableField("stock")
        private Integer stock;//库存
    }
    
  • 创建订单微服务模块shop_order 端口809X
  1. 右键工程,新建模块,此模块需要创建SpringBoot项目,模块名称shop_order

  2. 编写pom文件

    <?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>
            <artifactId>springCloud_test</artifactId>
            <groupId>com.dong</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <!--此模块信息-->
        <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.dong</groupId>
                <artifactId>shop_common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>
    
  3. 删除test目录

  4. 编写yaml配置文件

    配置端口号和数据源

    server:
      port: 8091    # 配置端口号
    spring:
      application:
        name: server-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: 123456
    
  5. 写Dao、Service、Controller三层

    OrderMapper

    @Mapper
    public interface OrderMapper extends BaseMapper<Order> {
    
    }
    

    Service接口

    import com.baomidou.mybatisplus.extension.service.IService;
    import com.dong.domain.Order;
    
    public interface IOrderService extends IService<Order> {
        //创建订单
        void createOrder(Order order);
    }
    

    Serivce实现类

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

    Controller

    @RestController
    @RequestMapping("/order")
    public class OrderController {
        @Autowired(required = false)
        private IOrderService orderService;
    
        @Autowired(required = false)
        private RestTemplate restTemplate;
    
        // 模拟下订单业务
        @RequestMapping("/save/{pid}")
        public Order order (@PathVariable("pid") int pid){
            System.out.println(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.save(order);
    
            return order;
        }
    
  6. 因为要实现业务之间的通讯,需要用到RestTemplate,需要注入容器,可以在启动类中写,也可以写配置类@Bean注入容器

    @Configuration
    public class RestConfig {
      @Bean
      public RestTemplate getRestTemplate(){
        return new RestTemplate();
      }
    }
    
  • 创建商品微服务模块shop_product 端口号808X
  1. 编写pom文件之前操作和shop_order项目相同,模块名shop_product

  2. 编写pom文件

    <?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>
            <artifactId>shop_order</artifactId>
            <groupId>com.dong</groupId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
    
        <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.dong</groupId>
                <artifactId>shop_common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    </project>
    
  3. yaml配置文件

    server:
      port: 8081
    spring:
      application:
        name: server-product
      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: 123456
    
  4. Dao、Service、Controller三层

    ProductMapper

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.dong.domain.Product;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface ProductMapper extends BaseMapper<Product> {
    
    }
    

    IProductService

    import com.baomidou.mybatisplus.extension.service.IService;
    import com.dong.domain.Product;
    
    public interface IProductService extends IService<Product> {
    
    }
    

    ProductServiceImp

    @Service
    public class ProductServiceImp extends ServiceImpl<ProductMapper, Product> implements IProductService {
    }
    

    Controller

    @RestController
    @RequestMapping("/product")
    public class ProductController {
        @Autowired
        private IProductService productService;
    
        // 按Id查询商品
        @RequestMapping("/{id}")
        public Product getProductById(@PathVariable("id") int id){
            Product product = productService.getById(id);
            return product;
        }
    
    }
    
  • 创建用户服务模块shop_user 端口号807X
  1. 创建模块,SpringBoot项目,项目名称shop_user,编写pom文件之前操作都相同

  2. pom文件

    <?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">
        <parent>
            <artifactId>springboot_cloud_alibaba</artifactId>
            <groupId>com.dong</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.dong</groupId>
                <artifactId>shop_common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>
    
  3. Dao、Service、Controller三层

    UserMapper

    @Mapper
    public interface UserMapper extends BaseMapper<USer> {
    
    }
    

    IUserService

    public interface IUserService extends IService<USer> {
    }
    

    UserServiceImp

    @Service
    public class UserServiceImp  extends ServiceImpl<UserMapper, USer> implements IUserService {
    
    }
    

    UserController

    @RestController("/user")
    public class UserController {
      @Autowired
      private IUserService userService;
    }
    

测试:

同时启动两个服务:shop_order和shop_product,访问localhost:8091/order/save/2

postman测试如下

在这里插入图片描述

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

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

相关文章

Jenkins中强制停止停不下来的job

# Script console 执行脚本 Jenkins 的提供了 script console 的功能&#xff0c;允许你写一些脚本&#xff0c;来调度 Jenkins 执行一些任务。 我们就可以利用 script console 来强制停止 job 执行。 首先进入 Jenkins 的 script console 页面&#xff1a; script console 路…

8.指令格式,指令的寻址方式

目录 一. 指令格式 二. 扩展操作码 三. 指令寻址 &#xff08;1&#xff09;指令寻址 &#xff08;2&#xff09;数据寻址 1.直接寻址 2.间接寻址 3.寄存器寻址 4.寄存器间接寻址 5.隐含寻址 6.立即寻址 7.基址寻址 8.变址寻址 9.相对寻址 10.堆栈寻址 一. 指令…

HTML 之常用标签的介绍

文章目录 h标签p标签a标签img 标签table、tr、td标签ul、ol、li 标签div 标签 h标签 <h> 标签用于定义 HTML 文档中的标题&#xff0c;其中 h 后面跟着一个数字&#xff0c;表示标题的级别。HTML 提供了 <h1> 到 <h6> 六个不同级别的标题&#xff0c;其中 &…

bclinux aarch64 ceph 14.2.10 对象存储 http网关 CEPH OBJECT GATEWAY Civetweb

相关内容 bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds&#xff1a; ceph-deploy mds-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【3】vdbench fsd 文件系统测试-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【2】vdbench rbd 块设…

桥接模式 rust和java的实现

文章目录 桥接模式介绍应用实例优点缺点使用场景关键角色 实现javarsut rust代码仓库 桥接模式 桥接&#xff08;Bridge&#xff09;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间…

JS操作canvas

<canvas>元素本身并不可见&#xff0c;它只是创建了一个绘图表面并向客户端js暴露了强大的绘图API。 1 <canvas> 与图形 为优化图片质量&#xff0c;不要在HTML中使用width和height属性设置画布的屏幕大小。而要使用CSS的样式属性width和height来设置画布在屏幕…

STM32中独立看门狗和窗口看门狗的使用方法

独立看门狗&#xff08;Independent Watchdog&#xff0c;IWDG&#xff09;和窗口看门狗&#xff08;Window Watchdog&#xff0c;WWDG&#xff09;是STM32微控制器中提供的两种看门狗定时器。看门狗定时器是一种硬件计时器&#xff0c;用于监视系统的运行状态&#xff0c;并在…

HTTP/2.0协议详解

前言 HTTP/2.0&#xff1a;互联网通信的革新标准 随着互联网技术的飞速发展&#xff0c;HTTP协议作为互联网应用最广泛的通信协议&#xff0c;也在不断演进和优化。HTTP/2.0是HTTP协议的最新版本&#xff0c;它旨在提供更高效、更安全、更快速的互联网连接。 一、HTTP/2.0的…

​软考-高级-系统架构设计师教程(清华第2版)【第6章 数据库设计基础知识(234~262)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第6章 数据库设计基础知识&#xff08;234~262&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测

多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测 目录 多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果…

XUbuntu22.04之安装pkg-config(一百九十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

机器学习—基本术语

目录 1.样本&#xff08;示例&#xff09; 2.属性 3.属性值 4.属性空间 5.样本空间 6.学习&#xff08;训练&#xff09; 7.数据集 8.测试 9.假设 10.学习器 11.标记 12.样例 13.标记空间&#xff08;样例空间&#xff09; 14.分类与回归 15.有监督学习、无监督…

【HUST】网安纳米|2023年研究生纳米技术考试参考

目录 1 纳米材料是什么 2 纳米材料的结构特性 3 纳米结构的其他特性 4 纳米结构的检测技术 5 纳米材料的应用 打印建议&#xff1a;PPT彩印&#xff08;这样重点比较突出&#xff09;&#xff0c;每面12张PPT&#xff0c;简单做一下关键词目录&#xff0c;亲测可以看清。如…

AWTK实现汽车仪表Cluster/DashBoard嵌入式GUI开发(七):FREERTOS移植

前言: 一般的GUI工程都需要一个操作系统,可能是linux,重量级的,也可能是FreeRTOS,轻量级的。 一句话理解那就是工程就是FreeRTOS task任务的集合。 一个main函数可以看到大框架: 很显然,除了第一个是硬件配置的初始化,中间最重要的部分就是要创建任务,把AWTK的应用…

DDR SDRAM 学习笔记

一、基本知识 1.SDRAM SDRAM : 即同步动态随机存储器&#xff08;Synchronous Dynamic Random Access Memory&#xff09;, 同步是指其时钟频率与对应控制器&#xff08;CPU/FPGA&#xff09;的系统时钟频率相同&#xff0c;并且内部命令 的发送与数据传输都是以该时钟为基准…

竞赛选题 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

EasyExcel入门使用教程

文章目录 简介一、工程创建&#x1f391;二、读操作&#x1f38a;二、写操作&#x1f384;总结 简介 数据导入导出意义 后台管理系统是管理、处理企业业务数据的重要工具&#xff0c;在这样的系统中&#xff0c;数据的导入和导出功能是非常重要的&#xff0c;其主要意义包括以下…

了解STM32看门狗定时器的工作原理和原则

STM32 系列微控制器的看门狗定时器 (Watchdog Timer&#xff0c;WWDG) 是一种重要的硬件资源&#xff0c;用于检测系统的异常状态&#xff0c;并在发生异常时执行特定的操作&#xff0c;以确保系统能够正常运行。在本文中&#xff0c;我将详细介绍 STM32 看门狗定时器的工作原理…

Java Elasticsearch 按一定时间间隔(timeInterval)循环查询数据

最近有个需求&#xff0c;前端传入时间间隔&#xff0c;去elasticsearch按照时间间隔统计每个时间间隔内数据量。 public List<HashMap<String,Object>> getCount(RequestParam Integer time, RequestParam String selectedDatedTime) {SimpleDateFormat format n…

Oracle(2-3) Basic Oracle Net Server Side Configuration

文章目录 一、基础知识1、The Listener Process监听器进程2、Connection Methods 连接方法3、Spawn and Bequeath Conn4、Direct Hand-Off Connections 直接切换连接5、Redirection Session 重定向会话6、Simple to Complex:N-Tier 简单到复杂&#xff1a;N层7、Service Config…