• 【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 {
       @Autowired
       private OrderService orderService;
        @GetMapping("/{orderId}")
        public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
            // 根据id查询订单并返回
            return orderService.queryOrderById(orderId);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    根据id查询订单,返回值是Order对象,如图

    在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 {
    
        @Autowired
        private UserService userService;
        /**
         * 路径: /user/110
         *
         * @param id 用户id
         * @return 用户
         */
        @GetMapping("/{id}")
        public User queryById(@PathVariable("id") Long id) {
            return userService.queryById(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    查询的结果如图:

    **案例需求:**修改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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    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);
        }
    
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    实现远程调用:

    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 {
    
        @Autowired
        private OrderMapper orderMapper;
        @Autowired
        private 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数据到order
            order.setUser(user);
            // 4.返回
            return order;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    亚马逊频繁扫号下的跨境电商,跨境电商卖家应该何去何从?
    扩展的多曝光图像合成算法及其在单幅图像增强中的应用。
    PMP有没有必要续证?
    Golang可能会踩的58个坑之初级篇
    PyQt5的笔记(中-4)
    Bevy的一些窗口设置
    nodejs+express设置和获取cookie,session
    认证授权与JWT
    C语言练习百题之求100之内的素数
    linux安装FSL
  • 原文地址:https://blog.csdn.net/m0_65462447/article/details/134558608