SpringCloud学习笔记

news2025/4/6 8:01:09

SpringCloud学习笔记

  • 成熟分布式微服务架构包含技术模块
  • SpringCloud与SpringBoot版本选择
  • SpringCloud各技术模块的技术选择
  • SpringCloud实现订单-支付微服务
    • 创建父工程(管理子工程即各个微服务)
      • 父工程的build.gradle配置
      • 父工程的settings.gradle配置
    • 创建支付子工程(payment_native)
      • 支付微服务具体业务类及目录结构
        • 目录结构
        • 具体业务类
    • 创建订单子工程(order_native)
      • build.gradle配置文件
      • 订单微服务具体业务类及目录结构
        • 目录结构
        • 具体业务类
    • 拆分目的

成熟分布式微服务架构包含技术模块

服务的注册与发现、服务调用、服务熔断、负载均衡、服务降级、服务消息队列、配置中心管理、服务网关、服务监控、全链路追踪、自动化构建部署、服务定时任务调度操作等等…

SpringCloud与SpringBoot版本选择

通过查看SpringCloud官网的推荐搭配即可。
更细致的搭配可以通过访问网址,查看返回的JSON串来获取。
JSON串解析网站

SpringCloud各技术模块的技术选择

服务注册中心:Eureka(可被Nacos代替)
服务调用:Ribbon(推荐LoadBalancer)
服务调用2:Feign(可被OpenFeign代替)
服务降级:Hystrix(可被sentienl代替)
服务网关:gateway
服务配置:Config(可被Nacos代替)
服务总线:Bus(可被Nacos代替)

SpringCloud实现订单-支付微服务

创建父工程(管理子工程即各个微服务)

正常新建Gradle项目


这里命名为CloudParent

由于父工程的主要作用是管理底下的各个子工程(微服务)所以不需要实现具体的业务,可以将它的src包删除,如下:

父工程的build.gradle配置

一般在父工程的build.gradle中引入一些子工程通用的依赖和配置,这样在每个子工程中就无需重复引入了,如下:

// 父工程配置
plugins {
    // 可以使用api编译
    id 'java-library'
    id 'org.springframework.boot' version '2.5.6'
    id 'io.spring.dependency-management' version '1.1.0'
}

ext {
    springCloudVersion = '2020.0.6'
    springBootVersion = '2.5.6'
    slf4jVersion = '1.7.25'
    logbackVersion = '1.2.3'
}

repositories {
    mavenCentral()
}

// 全局配置
allprojects {
    group 'org.gks.springcloud'
    version '1.0-SNAPSHOT'
    // 指定jdk版本
    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'
    //业务编码字符集,注意这是指定源码解码的字符集[编译器
    compileJava.options.encoding "UTF-8"
    //测试编码字符集,注意这是指定源码解码的字符集[编译器]
    compileTestJava.options.encoding "UTF-8"
    //编译JAVA文件时采用UTF-8 :注意这是指定源码编码的字符集【源文件】
    tasks.withType (JavaCompile) {
        options.encoding = "UTF-8"
    }
    //编译JAVA文件时采用UTF-8 :注意这是指定文档编码的字符集【源文件】
    tasks.withType (Javadoc) {
        options.encoding = "UTF-8"
    }
}

// 子项目的通用配置
subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    // 可以使用api编译
    apply plugin: 'java-library'

    jar.enabled = true

    repositories {
        mavenCentral()
    }

    // 子项目通用依赖
    dependencies {
        implementation "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        implementation "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
        implementation "ch.qos.logback:logback-classic:${logbackVersion}"
        implementation 'org.projectlombok:lombok'
    }

}

父工程的settings.gradle配置

目前只有一个父工程,所以其中只有如下配置(当前工程作为root):

后续随着子工程的不断加入,settings.gradle中会不断include新工程。见后续章节

创建支付子工程(payment_native)

右击父工程选择new–》Module:

在弹出的对话框中继续选择创建Gradle项目

下一步,输入子工程名称,注意此时父工程已经指定了

点击finish,一个子工程就初步创建完毕了:

此时观察子工程的目录发现只有一个build.gradle,此时需要修改该配置文件,将多余部分删除只需要引入当前子工程所需的依赖和配置即可,因为通用的已经在父工程的配置文件中指定:

  1. 初始配置
plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}
  1. 修改后配置
plugins {

}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'mysql:mysql-connector-java:8.0.26'
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'com.baomidou:mybatis-plus-boot-starter:3.3.2'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.aspectj:aspectjweaver:1.8.7'
}

修改完成后reload一下Gradle即可
build完成后通过侧边栏观察当前子工程所引入的依赖,发现不仅包含自己引入的也包含了父工程引入的:

但是此时该子项目的目录中依旧只有一个build.gradle配置文件,此时可以手动创建一个SpringBoot项目的常用目录:

在弹出的对话框中选择所需的模板目录结构:

这样创建完成后,就回到了我们熟悉的目录结构:

然后按需创建实现业务的包和类即可,别忘了SpringBoot的启动类和application.properties配置文件!!!

此时回到父工程中观察settings.gradle配置文件发现该子工程已经被自动引入了:

支付微服务具体业务类及目录结构

目录结构

具体业务类

实体类

//订单表实体类,包括主键(id)和订单序列号(serial)
public class Payment {
    private Long id;
    private String serial;

   	无参和全参构造函数

	setter和getter
}
//统一响应实体类,包括响应码、响应信息和响应数据
public class CommandResult<T> {

    private Integer code;
    private String message;
    private T data;

   	无参、两参和全参构造函数

	setter和getter
}

controller层

@RestController
@RequestMapping("payment")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @PostMapping("newData")
    public CommandResult create(@RequestBody Payment payment){
        Integer result = paymentService.create(payment);
        if (result != 0){
            return new CommandResult(200,"插入数据成功",result);
        }
        return new CommandResult(200,"插入数据失败",null);
    }

    @GetMapping("serialNum")
    public CommandResult getPaymentById(Long id){
        Payment result = paymentService.getPaymentById(id);
        return new CommandResult(200,"查询数据成功",result);
    }
}

service层

//接口
public interface PaymentService {
    Integer create(Payment payment);

    Payment getPaymentById(@Param("id") Long id);
}

//实现类
@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentDAO paymentDAO;

    @Override
    public Integer create(Payment payment) {
        return paymentDAO.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDAO.getPaymentById(id);
    }
}

DAO层及映射XML

public interface PaymentDAO {
    Integer create(@Param("payment")Payment payment);

    Payment getPaymentById(@Param("id") Long id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gks.pay.repository.PaymentDAO">
    <sql id="allValumns" >
        id,
        serial
    </sql>

    <insert id="create" parameterType="Payment" >
        INSERT INTO
            payment(serial)
        VALUES(#{payment.serial})
    </insert>

    <select id="getPaymentById" parameterType="Long" resultType="Payment">
        SELECT
            <include refid="allValumns"></include>
        FROM
            payment
        WHERE
            id=#{id}
    </select>
</mapper>

创建订单子工程(order_native)

创建流程与创建支付子工程基本一致,因为订单子工程是向前端提供访问接口的微服务,不需要实现具体功能所以无需访问数据库,也就不用引入数据库相关的依赖。

build.gradle配置文件

plugins {

}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.aspectj:aspectjweaver:1.8.7'
}

订单微服务具体业务类及目录结构

目录结构

具体业务类

RestTempleteConfig
因为要使用restTemplate所以需要进行配置并注入Bean
这里使用的是默认配置

@Configuration
public class RestTempleteConfig {

    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

实体类
与支付微服务中的一致

controller层

@RestController
@RequestMapping("order")
public class OrderController {

    public static final String PAYMENT_URL = "http://localhost:8085/payment";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("newData")
    public CommandResult create(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/newData", payment,CommandResult.class);
    }

    @GetMapping("serialNum")
    public CommandResult getPaymentById(Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/serialNum?id={id}", CommandResult.class, id);
    }
}

restTemplate的使用方式和坑见以下文章:
关于RestTemplate postForObject方法请求 服务端Controller接受不到值的问题解决
关于getForObject()的正确用法
一文吃透接口调用神器RestTemplate

自此两个微服务搭建完成

拆分目的

支付微服务实现具体的业务(比如这里的新增订单、查询订单)
而订单微服务只是提供与前端交互的接口,其内部本质是对支付微服务的请求

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

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

相关文章

物联网开发笔记(64)- 使用Micropython开发ESP32开发板之控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程:控件显示

一、目的 这一节我们学习如何使用我们的ESP32开发板来控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程&#xff1a;控件显示。 二、环境 ESP32 ILI9341 3.2寸TFT-LCD触摸屏 Thonny IDE 几根杜邦线 接线方法&#xff1a;见前面文章。 三、滑杆代码 import lvgl as lv i…

北京理工大学汇编语言复习重点

汇编是半开卷&#xff0c;可以带纸质资料。理论上&#xff0c;学好了以后&#xff0c;带本书进去就ok了&#xff0c;但是这次是线上&#xff0c;我还没书&#xff0c;就对着考试重点整理一点资料用于打印吧。 因为是线上&#xff0c;所以第4章基本不考框架了&#xff0c;浮点操…

工业4.0,科技引发产业革命,MES系统是数字化工厂的核心

当前&#xff0c;把握工业4.0时代信息技术引发的产业革命风口期&#xff0c;促进产业数字化转型升级&#xff0c;构建产业竞争新格局&#xff0c;实现弯道超车是难得一遇的大好时机&#xff0c;是局势所趋。在这样的大环境下&#xff0c;顺应全世界产业革命趋势&#xff0c;将数…

python的安装

python可以在所有操作系统上运行&#xff0c;但不同操作系统的安装方法有所不同 以&#xff1a;Mac OS X 和 Windows为例 为了安装 Python 并能正常使用&#xff0c;请根据你的操作系统安装提示&#xff0c;按照相应的步骤来操作。 我们还将进行一系列的测试&#xff0c;确保一…

SpringBoot实战(十)集成多数据源dynamic-datasource

目录1.Maven依赖2. DS注解3.普通Hihari连接池3.1 yml配置4.Druid连接池4.1 Druid依赖4.2 yml配置4.3 排除原生的Druid配置5. UserController6. UserServiceImpl7.测试7.1 新增数据7.2 查询数据7.3 测试结果8.源码地址&#xff1a;dynamic-datasource-spring-boot-starter 是一个…

【大数据入门核心技术-Kafka】(四)Kafka常用shell命令

目录 一、准备工作 1、Zookeeper集群安装 2、Kafka集群安装 二、常用Shell命令 1、创建Topic 2、查看创建的Topic 3、查看某一个Topic的详细信息 4、修改Topic 5、删除Topic 6、生产者发布消息命令 7、消费者接受消息命令 8、查看kafka节点数目 9、查看kafka进程 一…

再学C语言8:数据类型(6)——float和其他类型

一、_Bool类型 _Bool类型由C99引入 _Bool类型用于表示布尔值&#xff1a;逻辑值true&#xff08;真&#xff09;和false&#xff08;假&#xff09; C用值1表示true&#xff0c;用值0表示false&#xff0c;所以_Bool类型本质上也是一种整数类型 二、float、double和long do…

查找排序编程题——二分查找+冒泡排序‍♀️

目录 7-1 二分查找 输入格式: 输出格式: 输入样例: AC&#xff1a; 7-2 冒泡法排序 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; AC&#xff1a; 附&#xff1a; 分享&#x1f31e; &#xff1a; 前途与玫瑰 来日与方…

尝试使用LTTng+TraceCompass分析一下进程周期偏移

准备工作 我先是在板子里通过LTTng Stream的方式将log保存在了上位机里。 然后在上位机中打开TraceCompass分析log。 导出整理log数据 然后我在events表格中搜索我的进程名&#xff0c;发现主要是sched_switch sched_waking sched_wakeup这三类。 然后我又搜索了一下&#x…

10个最好的WordPress RSS插件比较(2022)

您是否正在为您的网站寻找最好的 WordPress RSS 提要插件&#xff1f; RSS 提要插件可以轻松地自动从其他网站提取内容并将其显示在您的网站上。它们还可用于提高参与度、增加流量和增加页面浏览量。 在本文中&#xff0c;我们将分享我们挑选的可在您的网站上使用的最佳 Word…

远眺捷码智慧乡村方案赋能乡村治理,打造更智慧更宜居的乡村

01.智慧乡村治理重要性 “智慧乡村”是以云计算、大数据应用、地理信息系统网络、物联网技术为核心&#xff0c;通过构建服务于政务管理、农业增收、民生幸福等方面的系统应用平台&#xff0c;将社会基础信息、产业发展、环境监测、医疗卫生、劳动保障、社会管理、公共服务等要…

全面便捷的数据管理能力,助力数据运营降本增效

对于任何企业来说&#xff0c;销售和供应链总是天平秤座的两端。如何放置两个砝码是对企业管理能力的极大考验。今天&#xff0c;让我们来谈谈供应链管理的例子来探讨一下对于报表工具而言&#xff0c;怎么样才能让客户全面、便捷的全局管理数据接入。背景&#xff1a;有序的供…

SPRING-了解4-AOP1

主要理念&#xff1a;不用继承&#xff0c;而是用Java Reflect类中的Proxy来实现对方法的增强 面向切面编程 oop的延续&#xff0c;对业务进行隔离&#xff0c;降低耦合度&#xff0c;目标是不改变原来的代码在主干中增加新功能 比如已经写好登录功能&#xff0c;现在需要加…

【大数据技术】流数据、流计算、Spark Streaming、DStream的讲解(图文解释 超详细)

流数据和流计算 在大数据时代&#xff0c;数据可以分为静态数据和流数据&#xff0c;静态数据是指在很长一段时间内不会变化&#xff0c;一般不随运行而变化的数据。流数据是一组顺序、大量、快速、连续到达的数据序列&#xff0c;一般情况下数据流可被视为一个随时间延续而无…

脑白质WM中的血流动力学响应函数HRF的特性

血流动力学响应函数HRF 估计BOLD信号的血流动力学响应函数(HRF)对于解释和分析与事件相关的fMRI数据至关重要广义线性模型(GLM)假设BOLD信号是真实反应与HRF进行卷积而得到的 一般来说&#xff0c;白质中功能激活的检测灵敏度远低于灰质&#xff0c;并且激活区域一般较小 原因…

[附源码]Nodejs计算机毕业设计健身房管理系统设计Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

J-003 Jetson电路设计之USB设计--NANO XAVIER NX

USB设计1 简介2 框图介绍3 USB HUB设计3.1电源部分3.2 芯片引脚3.3 晶振电路4 电源控制4.4 电源开关电路设计4 调试USB电路设计1 简介 NANO & XAVIER NX提供三路USB接口&#xff0c;其中包含一路调试USB&#xff08;用于镜像下载&#xff09;和一路USB3.2接口。引脚说明: …

编码踩坑——MySQL更新存放JSON的字段、\“ 转义成 “

本篇介绍在执行MySQL线上变更时遇到的问题&#xff0c;表现为"更新JSON字段时&#xff0c;实际更新的值与SQL语句中的值不一致&#xff0c;JSON格式错误"&#xff0c;如下&#xff1b; 问题描述 处理线上问题&#xff0c;需要新插入一条记录&#xff1b;将原JSON粘贴…

Jenkins(2)— 配置webhooks触发器

1、项目配置 项目配置 >> 构建触发器 >> 选择Gitee webhook触发器 生成Gitee WebHook密码&#xff1a;46d678257c0399b105635bcb9722ea09 2、Gitee配置 Gitee项目 >> 管理 >> 配置WebHooks 注意&#xff1a; 由于我的jenkins是部署在本地的&#xff…

element-ui+js+vue——实现图片的放大缩小拖动等功能——技能提升

elementuijsvue——实现图片组件的封装 1. 实现图片的放大缩小 2. 实现图片的拖动功能 3. 实现图片的预览最近同事在写一个关于 图片放大缩小拖动的功能&#xff0c;其实不止是图片&#xff0c;只要是在以下组件中的内容&#xff0c;都是可以支持放大缩小拖动的。 功能&#x…