Java阶段五Day16

Java阶段五Day16

文章目录

  • Java阶段五Day16
    • 问题解析
      • 启动servlet冲突问题
      • nacos注册中心
      • 用户信息验证失败
      • 前端效果不对
      • 前端请求到后台服务的流转过程
    • 远程dubbo调用
      • 业务需求
      • dubbo配置
      • xml配置
      • domain层代码 补充远程调用
    • 师傅详情
      • 接口抽象
      • 开发
        • WorkderServerController
        • WorkerServerService
        • WorkerRepository
        • WorkerDao
        • WorkerMapper.xml
      • 问题
      • 展示师傅信息
    • 准备好后续开发的环境
      • worker-admin删除保留开发框架
      • 日志框架

问题解析

启动servlet冲突问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-24R4r4OO-1691147415831)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day15/assets/image-20230727174543269.png)]

解决方法:启动项目main 将传递过来servlet-api依赖去除

nacos注册中心

  • 依赖
  • yaml配置

用户信息验证失败

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pFT83xux-1691147415832)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day15/assets/image-20230727145931514.png)]

断点查看源代码 LoginUserFilter(在处理网关解析后的jwt数据 userJson字符串)

如果过滤器不生效,就会导致解析userJson没执行,后端代码获取LongUser对象是空

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EmNRNN8J-1691147415833)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091248153.png)]

LongUserFilterAutoConfiguration 需要满足条件才会帮助项目程序创建过滤器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JkJPh035-1691147415833)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091404276.png)]

所以根据源码分析,第一个条件没满足,导致当前LoginUserFilter没有自动配置.,无法生效

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gd9Fc7Y7-1691147415834)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091638017.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HD7wxcu-1691147415835)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091713931.png)]

passport-sdk包中提供了一个FastJsonAutoConfiguration

FastJson实现的自动配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eVDuh9QP-1691147415835)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728092205409.png)]

  1. 要解析用户userJson,要经过过滤器LoginUserFilter
  2. 过滤器生效(bean对象),自动配置类条件要满足(容器具备一个Json实现bean对象)
  3. 所以要求FastJsonAutoConfiguration要满足条件,json.provider=fastjson
  4. 当前系统不满足这个条件

根据上述分析,在yaml文件中

提供属性

json:
	provider: fastjson

前端效果不对

当前worker-server端:师傅入驻

  • nacos
  • passport
  • attach
  • gateway
  • worker-server

正常执行了入驻功能,但是前端没有反馈成功,因为响应没有做处理,直接返回的是controller的方法返回值,需要返回Result的对象

{
    "code":200,
    "message":"成功"
    "data":{},
	"success":true
}

源代码中每个 main 模块中有非常多配置类

  1. 第一个是全局异常捕获
  2. 接口文档插件配置
  3. 配置springmvc cors(当前没有) 防止 knife4j 接口文件响应异常
  4. WebResponseHander 将响应做统一处理输出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x65ExouP-1691147415836)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728094521894.png)]

这个方法执行位置在controller返回数据之后,响应返回前端之前

controller返回值如果不满足要求,就会统一封装成Result对象

body就是controller返回数据

前端请求到后台服务的流转过程

  • http://localhost:8989/api/worker/create 发给前端代理(vue.config.js
  • http://localhost:8097/worker/create 进入网关
  • lb://luban-worker-server/worker/create 找到路由断言匹配,负载均衡服务
  • http://localhost:9001/worker/create 进入controller逻辑

远程dubbo调用

业务需求

当前worker入驻,要调用attach-server服务,实现图片数据更新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bNKXEy7e-1691147415836)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728103127991.png)]

缺少的功能是师傅入驻,远程调用attach将图片数据库数据 businessType=77(worker业务) businessId=(生成的师傅id)

dubbo配置

  • 依赖
  • yaml(自动配置中属性,目的就是给配置类用的)
  • 注解

这种自动配置的使用方式,不符合分层开发目的,避免业务侵入性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1R8eB6aR-1691147415837)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728103519634.png)]

xml配置

  • 依赖 dubbo
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.8</version>
</dependency>
  • xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://dubbo.apache.org/schema/dubbo
    http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    <!--配置dubbo 原来在yaml自动配属性中看到 xml中也有-->
    <!--dubbo应用-->
    <dubbo:application name="${spring.application.name}">
        <!--关闭qos-->
        <dubbo:parameter key="qos.enable" value="false"/>
    </dubbo:application>
    <!--protocol dubbo -1-->
    <dubbo:protocol name="dubbo" port="-1"/>
    <!--注册中心-->
    <dubbo:registry
            id="dubboNacos"
            protocol="nacos"
            address="localhost:8848"
            use-as-config-center="false"
            use-as-metadata-center="false"/>
    <!--消费者配置接口-->
    <dubbo:reference id="attachApi" interface="com.tarena.tp.attach.server.client.AttachApi"
                 check="fasle" registry="dubboNacos"/>   
</beans>
  • 依赖provider接口 添加到调用模块domain
<!--远程调用attach-->
<dependency>
    <groupId>com.tarena.tp.attach</groupId>
    <version>1.0.0-SNAPSHOT</version>
    <artifactId>luban-attach-server-client-api</artifactId>
</dependency>
  • 导入到当前启动worker-server进程中@ImportResource

domain层代码 补充远程调用

saveWorker方法中远程调用

import com.tarena.luban.worker.server.repository.WorkerAreaRepository;
import com.tarena.luban.worker.server.repository.WorkerCategoryRepsoitory;
import com.tarena.luban.worker.server.repository.WorkerRepository;
import com.tarena.passport.protocol.LoginUser;
import com.tarena.passport.sdk.context.SecurityContext;
import com.tarena.tp.attach.server.client.AttachApi;
import com.tarena.tp.attach.server.param.AttachUpdateParam;
import com.tarena.tp.luban.worker.server.common.enums.ResultEnum;
import com.tarena.tp.luban.worker.server.dto.param.IdCardParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerAreaParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCategoryParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCreateParam;
import com.tedu.inn.commons.utils.Asserts;
import com.tedu.inn.protocol.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author java@tedu.cn
 * @version 1.0
 */
@Service
@Slf4j
public class WorkerServerService {
    @Autowired
    private WorkerRepository workerRepository;
    @Autowired
    private WorkerAreaRepository workerAreaRepository;
    @Autowired
    private WorkerCategoryRepsoitory workerCategoryRepsoitory;
    //domain不关心实现,没有实现,报错
    @Autowired
    private AttachApi attachApi;
    /**
     * 1. 补充userId
     * 2. 检查 手机号
     * 3. 检查 身份证 和真实名称是否匹配 TODO
     * 4. 存储 worker workerCategory workerArea
     * 使用定义好的repository接口
     * @param workerCreateParam
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Long create(WorkerCreateParam workerCreateParam) throws BusinessException {
        //获取userId
        Long userId=getUserIdByToken();
        //检查 手机号 身份证 UNDO
        checkPhoneAndIdCard(workerCreateParam);
        //挨个存储对应数据到持久层
        workerCreateParam.setUserId(userId);
        Long id=saveWorker(workerCreateParam);
        saveWorkerArea(workerCreateParam);
        saveWorkerCategory(workerCreateParam);
        return id;
    }

    /**
     * 先删除,后新增
     * @param workerCreateParam
     */
    private void saveWorkerCategory(WorkerCreateParam workerCreateParam) {
        workerCategoryRepsoitory.deleteByUserId(workerCreateParam.getUserId());
        List<WorkerCategoryParam> workerCategoryParams = workerCreateParam.getWorkerCategoryParams();
        if (!CollectionUtils.isEmpty(workerCreateParam.getWorkerCategoryParams())){
            //循环
            workerCategoryParams.forEach(param -> {
                param.setUserId(workerCreateParam.getUserId());
                workerCategoryRepsoitory.save(param);
            });
        }
    }

    /**
     * 先删除,后新增
     * @param workerCreateParam
     */
    private void saveWorkerArea(WorkerCreateParam workerCreateParam) {
        workerAreaRepository.deleteByUserId(workerCreateParam.getUserId());
        //循环存储 <foreach>
        //TODO 批量存
        List<WorkerAreaParam> workerAreaParams
                = workerCreateParam.getWorkerAreaParams();
        for (WorkerAreaParam workerAreaParam : workerAreaParams) {
            //提交的参数 workerCategoryParam中和workerParam类似的,也没有userId;
            workerAreaParam.setUserId(workerCreateParam.getUserId());
            //insert into worker_area
            workerAreaRepository.save(workerAreaParam);
        }
    }

    /**
     * 1. 当前用户有可能已经是师傅了.
     * 1.1 先查讯数据库是否有当前用户.师傅信息 有就报错 没有 就新增
     * 1.2 不管有没有 如果有就删除.重新新增
     * @param workerCreateParam
     * @return
     */
    private Long saveWorker(WorkerCreateParam workerCreateParam) throws BusinessException {
        //如果当前用户在数据库中有师傅信息,就删除 重新入驻师傅信息
        workerRepository.delete(workerCreateParam.getUserId());
        Long id=workerRepository.save(workerCreateParam);
        //rpc 调用 将身份信息,worker-id,和当前图片传递给attach系统,做更新
        //远程调用
        try{
            //远程调用,更新已经上传的图片,绑定到当前worker
            createAttach(id,workerCreateParam.getAttachList());
        }catch (Exception e){
            //远程调用失败
            throw new BusinessException(ResultEnum.ATTACH_FAILED);
        }
        return id;
    }
    //人为定义的类型.
    private static final Integer bizType=100;
    private void createAttach(Long businessId, List<IdCardParam> attachList) {
        //要将attachList 图片(attach服务 没有绑定业务)
        //封装远程调用参数 attach执行一个简单update attach set bysiness_id=#{参数} business_id=#{师傅id}
        //where id=#{当前图片id}
        List<AttachUpdateParam> attachUpdateParams=new ArrayList<>();
        //封装
        for (IdCardParam idCardParam : attachList) {
            //参数元素
            AttachUpdateParam attachUpdateParam=new AttachUpdateParam();
            attachUpdateParam.setIsCover(idCardParam.getType());
            // 图片id bizId bizType 主要数据
            attachUpdateParam.setId(idCardParam.getId());
            attachUpdateParam.setBusinessType(bizType);
            attachUpdateParam.setBusinessId(businessId.intValue());
            //添加到list
            attachUpdateParams.add(attachUpdateParam);
        }
        //调用远程
        attachApi.batchUpdateAttachByIdList(attachUpdateParams);
    }

    private void checkPhoneAndIdCard(WorkerCreateParam workerCreateParam) {
        //UNDO
        log.info("check phone and idCard,now passed");
    }

    private Long getUserIdByToken() throws BusinessException {
        LoginUser loginToken = SecurityContext.getLoginToken();
        //判断 user登录还是没登录 如果loginUser是空的,说明没登录
        Asserts.isTrue(loginToken==null,
                new BusinessException(ResultEnum.USER_TOKEN_VERIFY_FAILED));
        return loginToken.getUserId();
    }
}

师傅详情

接口抽象

要素备注
请求地址/worker/detail
请求方式GET
请求参数解析userId
返回值WorkerVO

返回值说明WorderVO

AccountVO: 远程调用account服务 查询已经审核通过的师傅绑定的账号

List<WorkerAreaVO>: 师傅绑定区域.

List<WokrderCategoryVO>: 师傅绑定的服务种类.

List<AttachVO>: 师傅绑定的身份证图片

开发

WorkderServerController

WorkerServerService

WorkerRepository

WorkerDao

WorkerMapper.xml

问题

完成所有查询,封装好数据,到页面检测功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jz9bAOe8-1691147415838)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728155555011-16905309563751.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dOoh0WgM-1691147415838)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728155706992.png)]

思路: 通过检查对应代码位置,发现AccountBO暂时没有查询,会导致转化异常,所以在业务层返回添加一个假数据

展示师傅信息

当前已经注册成为师傅,但是前端没有消除成为师傅的按钮

审核数据 0 1 2(未注册) 3(已注册未审核)

准备好后续开发的环境

worker-admin删除保留开发框架

删除代码原则:

不删 / 保留

  • 数据封装对象: BO VO DTO PO PAGEQUERY

  • 转化的类:**Converter \*\*Asemble

  • 接口一律不删:

  • XML不删: 明白sql语句 增删拆改,条件作用

日志框架

当前luban-project使用日志框架

error debug info分到不同文件了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XQYfO6pv-1691147415838)(assets/image-20230728175103253.png)]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

51单片机学习-AT24C02数据存储秒表(定时器扫描按键数码管)

首先编写I2C模块&#xff0c;根据下面的原理图进行位声明&#xff1a; sbit I2C_SCL P2^1; sbit I2C_SDA P2^0;再根据下面的时序结构图编写函数&#xff1a; /*** brief I2C开始* param 无* retval 无*/ void I2C_Start(void) {I2C_SDA 1; I2C_SCL 1; I2C_SDA 0;I2C_S…

redis原理 6:小道消息 —— PubSub

前面我们讲了 Redis 消息队列的使用方法&#xff0c;但是没有提到 Redis 消息队列的不足之处&#xff0c;那就是它不支持消息的多播机制。 img 消息多播 消息多播允许生产者生产一次消息&#xff0c;中间件负责将消息复制到多个消息队列&#xff0c;每个消息队列由相应的消费组…

【Leetcode刷题】位运算

本篇文章为 LeetCode 位运算模块的刷题笔记&#xff0c;仅供参考。 位运算的常用性质如下&#xff1a; a ^ a 0 a ^ 0 a a ^ 0xFFFFFFFF ~a目录 一. 基本位运算Leetcode29.两数相除Leetcode89.格雷编码 二. 位运算的性质Leetcode136.只出现一次的数字Leetcode137.只出现一…

好用的数据库管理软件之idea(idea也有数据库???)

1.建立maven项目&#xff08;maven项目添加依赖&#xff0c;对于后期连接数据库很方便&#xff09; 2.连接数据库。。。 这里一定注意端口号&#xff0c;不要搞错了 和上一张图片不一样哦 3.数据库测试代码。。。 然后你就可以在这里边写MySQL代码了&#xff0c;这个工具对于新…

RunnerGo条件控制器使用方法

在做性能测试时我们需要根据业务需求、业务场景来配置测试脚本&#xff0c;举个例子&#xff1a;在登录注册场景中&#xff0c;可能会有账号密码全部正确、账号格式错误、密码错误等多种情况&#xff0c;这里的“登录/注册”事件可以视为一个场景。一个真实业务中的场景&#x…

人工智能学习07--pytorch23--目标检测:Deformable-DETR训练自己的数据集

参考 https://blog.csdn.net/qq_44808827/article/details/125326909https://blog.csdn.net/dystsp/article/details/125949720?utm_mediumdistribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-125949720-blog-125326909.235^v38^pc_releva…

【Python】Web学习笔记_flask(3)——上传文件

用GET、POST请求上传图片并呈现出来 首先还是创建文件上传的模板 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>上传图片</title> </head> <body> <form action""…

MySQL 远程操作mysql

可以让别人在他们的电脑上操作我电脑上的数据库 create user admin identified with mysql_native_password by admin; //设置账号密码都为admingrant all on *.* to admin; //给admin账号授权 授权完成

直播课 | 大橡科技研发总监丁端尘博士“类器官芯片技术在新药研发中的应用”

从类器官到类器官芯片&#xff0c;正在生物科学领域大放异彩。 药物研发需要新方法 众所周知&#xff0c;一款新药是一个风险大、周期长、成本高的艰难历程&#xff0c;国际上有一个传统的“双十”说法——10年时间&#xff0c;10亿美金&#xff0c;才可能成功研发出一款新药…

【安全测试】Web应用安全之XSS跨站脚本攻击漏洞

目录 前言 XSS概念及分类 反射型XSS(非持久性XSS) 存储型XSS(持久型XSS) 如何测试XSS漏洞 方法一&#xff1a; 方法二&#xff1a; XSS漏洞修复 原则&#xff1a;不相信客户输入的数据 处理建议 资料获取方法 前言 以前都只是在各类文档中见到过XSS&#xff0c;也进…

微信小程序animation动画,微信小程序animation动画无限循环播放

需求是酱紫的&#xff1a; 页面顶部的喇叭通知&#xff0c;内容不固定&#xff0c;宽度不固定&#xff0c;就是做走马灯&#xff08;轮播&#xff09;效果&#xff0c;从左到右的走马灯&#xff08;轮播&#xff09;&#xff0c;每播放一遍暂停 1500ms &#xff5e; 2000ms 刚…

Python web实战之 Django 的模板语言详解

关键词&#xff1a; Python、web开发、Django、模板语言 概要 作为 Python Web 开发的框架之一&#xff0c;Django 提供了一套完整的 MVC 模式&#xff0c;其中的模板语言为开发者提供了强大的渲染和控制前端的能力。本文介绍 Django 的模板语言。 1. Django 模板语言入门 Dj…

宇树Unitree Z1机械臂使用教程

宇树Unitree Z1机械臂使用教程 作者&#xff1a;Herman Ye Galbot Auromix Auromix是一个机器人爱好者组织&#xff0c;欢迎参与我们Github上的开源项目 更新日期&#xff1a;2023/08/04 注意&#xff1a;此文档在该日期下测试有效。 以下内容参考宇树官方的Z1 Docs。 由宇树…

JavaScript |(四)正则表达式 | 尚硅谷JavaScript基础实战

学习来源&#xff1a;尚硅谷JavaScript基础&实战丨JS入门到精通全套完整版 文章目录 &#x1f4da;正则表达式&#x1f4da;正则表达式字面量方式&#x1f4da;字符串&正则表达式&#x1f407;split()&#x1f407;search()&#x1f407;match()&#x1f407;replace()…

Vue3_语法糖—— <script setup>以及unplugin-auto-import自动引入插件

<script setup>import { ref , onMounted} from vue;let obj ref({a: 1,b: 2,}); let changeObj ()>{console.log(obj)obj.value.c 3 //ref写法}onMounted(()>{console.log(obj)})</script> 里面的代码会被编译成组件 setup() 函数的内容。 相当于 <…

牛客网Verilog刷题——VL51

牛客网Verilog刷题——VL51 题目答案 题目 请编写一个十六进制计数器模块&#xff0c;计数器输出信号递增每次到达0&#xff0c;给出指示信号zero&#xff0c;当置位信号set 有效时&#xff0c;将当前输出置为输入的数值set_num。模块的接口信号图如下&#xff1a; 模块的时序图…

Redis的Java客户端

目录 1.Jedis的使用 前置工作-ssh进行端口转发 JedisAPI的使用 Jedis连接池 2.SpringDataRedis的使用 1.创建项目 2.配置文件 3.注入RedisTemplate对象 4.编写代码 3.SpringRedisTemplate 哈希结构用法 ​总结 1.Jedis的使用 Jedis&#xff1a;以Redis命令作为方法…

mysql重置和修改密码 Ubuntu系统

忘记密码要重置密码 cat /etc/mysql/debian.cnf/etc/mysql/debian.cnf这个只有Debian或者Ubuntu服务器才有&#xff0c;里面有mysql安装后自带的用户&#xff0c;作用就是重启及运行mysql服务。我们用这个用户登录来达到重置密码的操作 使用上面的那个文件中的用户名和密码登…

强化学习分享(一) DQN算法原理及实现

摘要&#xff1a;主要讲解DQN算法的原理&#xff0c;伪代码解读&#xff0c;基于pytorch版本的DQN小游戏编程&#xff0c;同时对该代码进行详细标注&#xff0c;以及奉上原码。 &#xff08;一&#xff09;强化学习算法介绍 DQN&#xff0c;顾名思义&#xff0c;Deep Q Learni…

SpringCloud《Eureka、Ribbon、Feign、Hystrix、Zuul》作用简单介绍

概述 SpringCloud是一个全家桶&#xff0c;包含多个组件。 本文主要介绍几个重要组件&#xff0c;也就是Eureka、Ribbon、Feign、Hystrix、Zuul这几个组件。 一、业务场景介绍 业务流程&#xff0c;支付订单功能 订单服务改变为已支付订单服务调用库存服务&#xff0c;扣减…