当前位置: 首页 > news >正文

【SpringCloud】认识微服务、服务拆分以及远程调用

SpringCloud

1.认识微服务
1.1单体架构

单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署
在这里插入图片描述

单体架构的优缺点:

优点: 架构简单,部署成本低

缺点: 耦合度高(维护困难,升级困难)

1.2分布式架构

分布式架构:根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务
在这里插入图片描述

优点: 降低服务耦合,有利于服务升级和拓展

缺点: 服务调用关系错综复杂

分布式架构虽然降低了服务耦合,但是服务拆分时也有很多问题需要思考:服务拆分的粒度、服务之间调用、服务之间调用关系的管理,需要制定一套行之有效的标准来约束分布式架构。

1.3微服务架构

微服务的架构特征:

  • 单一职责:微服务拆分粒度小,每一个服务都对应唯一的业务能力,做到单一职责
  • 自治:团队独立,技术独立,独立部署和交付
  • 面向服务:服务提供统一标准的接口,与语言和技术无关
  • 隔离性强:服务调用做好隔离、容错、降级、避免出现级联问题

微服务是一种经过良好架构设计的分布式架构方案

SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud

SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配

其中常见的组件包括:

  • 服务注册发现:Eureka、Nacos、Consul
  • 服务远程调用:OpenFeign、Dubbo
  • 服务链路监控:Zipkin、Sleuth
  • 统一配置管理:SpringCloudConfig、Nacos
  • 统一网关路由:SpringCloudGateway、Zuul
  • 流控、降级、保护:Hystix、Sentinel

SpringCloud是微服务交媾的一站式解决方案,继承了各种优秀微服务功能组件

2.服务拆分

任何分布式架构都离不开服务的拆分,微服务也一样

微服务的拆分原则:

  • 不同微服务,不要重复开发相同的业务
  • 微服务数据独立,不要访问其他微服务的数据库
  • 微服务可以将自己的业务暴露为接口,供其他微服务调用
    在这里插入图片描述
3.远程调用

项目结构:
在这里插入图片描述

在order-service服务中,有一个根据id查询订单的接口:

package cn.itcast.order.web;import cn.itcast.order.pojo.Order;
import cn.itcast.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate OrderService orderService;@GetMapping("/{orderId}")public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {// 根据id查询订单并返回return orderService.queryOrderById(orderId);}
}

根据id查询订单,返回值是Order对象,如图
在这里插入图片描述
其中的user为null
在user-service中有一个根据id查询用户的接口:

package cn.itcast.user.web;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 路径: /user/110** @param id 用户id* @return 用户*/@GetMapping("/{id}")public User queryById(@PathVariable("id") Long id) {return userService.queryById(id);}
}

查询的结果如图:
在这里插入图片描述

**案例需求:**修改order-service中的根据id查询订单业务,要求在查询订单的同时,根据订单中包含的userId查询出用户信息,一起返回

分析:需要在order-service中向user-service发起一个http请求,调用http://localhost:8081/user/{userId}接口

步骤:

  • 注册一个RestTemplate的实例到Spring容器
  • 修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User
  • 将查询的User填充到Order对象中返回
package cn.itcast.order.pojo;
import cn.itcast.pojo.User;
import lombok.Data;
//Order实体类
@Data
public class Order {private Long id;private Long price;private String name;private Integer num;private Long userId;private User user;
}
package cn.itcast.order;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

实现远程调用:

package cn.itcast.order.service;import cn.itcast.feign.UserClient;
import cn.itcast.pojo.User;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public Order queryOrderById(Long orderId) {// 1.查询订单Order order = orderMapper.findById(orderId);//2.调用user微服务接口,根据userId得到用户信息String url = "http://userservice/user/" + order.getUserId();User user = restTemplate.getForObject(url, User.class);//3.封装user数据到orderorder.setUser(user);// 4.返回return order;}
}

相关文章:

  • 使用不平衡数据集练习机器学习
  • 物联网AI 无线连接学习之蓝牙基础篇 协议的发展
  • 2024年天津天狮学院专升本食品质量与安全专业《分析化学》考纲
  • 迪文科技工业串口屏(DMG10600C070-03WTC)更新程序烧录刷机
  • 【挑战业余一周拿证】一、亚马逊云科技简介 - 第 2 节 - 模块 简介
  • 【Java】实现一个自己的定时器
  • 4D Gaussian Splatting:用于实时的动态场景渲染
  • FinGPT:金融垂类大模型架构
  • leetcode设计循环队列(链表方式来实现)
  • UDP分片和丢包与TCP效果对比
  • 基于 Gin 的 HTTPS 代理 Demo
  • 【深入剖析K8s】容器技术基础(三):深入理解容器镜像 文件角度
  • Hive内置表生成函数
  • 什么是轻量应用服务器?可以从亚马逊云科技的优势入手了解
  • Unsupervised Skill Discovery via Recurrent Skill Training论文笔记
  • android图片蒙层
  • C++11: atomic 头文件
  • ES10 特性的完整指南
  • ES6核心特性
  • JavaScript的使用你知道几种?(上)
  • java小心机(3)| 浅析finalize()
  • JAVA之继承和多态
  • js数组之filter
  • js算法-归并排序(merge_sort)
  • RxJS: 简单入门
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Spring Boot MyBatis配置多种数据库
  • 码农张的Bug人生 - 初来乍到
  • 深度解析利用ES6进行Promise封装总结
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 学习JavaScript数据结构与算法 — 树
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​queue --- 一个同步的队列类​
  • # Apache SeaTunnel 究竟是什么?
  • #git 撤消对文件的更改
  • #NOIP 2014# day.2 T2 寻找道路
  • (bean配置类的注解开发)学习Spring的第十三天
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (十八)三元表达式和列表解析
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)编辑寄语:因为爱心,所以美丽
  • (转载)利用webkit抓取动态网页和链接
  • ***通过什么方式***网吧
  • *上位机的定义
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .Net Remoting常用部署结构
  • .net 调用php,php 调用.net com组件 --
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型