zoukankan      html  css  js  c++  java
  • 【分布式】SpringCloud(1)--基于RestTemplate构建简易微服务调用框架

    1.前言

    基于之前的博客中提到的分布式框架实现:

    SpringBoot整合分布式Dubbo+Zookeeper

    在SpringBoot中整合了分布式微服务组件Dubbo、Zookeeper,使用RPC通信方式实现了服务提供方Provider和服务消费方Consumer之间的远程接口调用。

    今天来学习大名鼎鼎的SpringCloud微服务框架,这里要讲到的是SpringCloud采用的是基于HTTP的Rest协议调用方式,使用到的最重要的Bean组件就是

    RestTemplate

    RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。虽然在性能上不如RPC远程调用,但是却不存在代码级别的强依赖,基于Restful风格的接口调用显得更为灵活。

    这种开发方式,在强调快速演化的微服务环境下,显得更加合适。

    下面这里将以简单地方式基于RestTemplate实现一个SpringBoot与Mybatis框架下的模块微服务通信方式,在此基础上再添加SpringCloud框架及其组件。也算是对之前

    的Dubbo和Zookeeper知识做了一次回顾对比学习。

    2.微服务框架构建

    2.1.整体服务框架依赖说明

     该项目有一个maven父模块,其中里面有三个子模块:

                                 springcloud_hello:整体父工程。

                                 springcloud-api:公共子模块,放公共实体对象。

      springcloud-provider-dept-8001:部门微服务提供者。提供微服务HTTP调用接口。

      springcloud-consumer-dept-8002:部门微服务消费者。调用部分微服务提供者接口进行CRUD操作。

    2.2.父工程构建

    创建简单的Maven项目springcloud_hello,配置主要的pom依赖、添加相应的组件:

    <!--打包方式为pom-->
        <packaging>pom</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <junit.version>4.12</junit.version>
            <log4j.version>1.2.17</log4j.version>
            <lombok.version>1.16.18</lombok.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <!--springcloud的依赖-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Greenwich.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--springboot依赖:2.1.4.RELEASE版本对应springcloud为Greenwich.SR1-->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>2.1.4.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--springboot启动器-->
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>1.3.2</version>
                </dependency>
                <!--日志和测试相关的包-->
                <dependency>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-core</artifactId>
                    <version>1.2.3</version>
                </dependency>
                <!--junit-->
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
                <!--lombok-->
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>${lombok.version}</version>
                </dependency>
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>${log4j.version}</version>
                </dependency>
                <!--数据库:mysql-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.47</version>
                </dependency>
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>1.1.12</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    View Code

    2.3.构建公共POJO项目api

    这里主要就是将springcloud-api添加至parent父项目的依赖中进行创建:

    <!--每添加一个子项目都会在这里面进行增加一个子module,服务
    提供者和调用者都是类似操作,不再累述-->
    <modules>
            <module>springcloud-api</module>
            <module>springcloud-provider-dept-8001</module>
            <module>springcloud-consumer-dept-8002</module>
    </modules>

    添加lombok组件,并创建POJO类:

    <!--当前的Module需要的依赖如果在父依赖中已经设置了版本号,
        这里就不需要再重复设置了-->
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    @Data
    @NoArgsConstructor
    @Accessors(chain = true)  //链式写法
    public class Dept{
        private Long deptno;
        private String dname;
        private String dbSource;
    
        public Dept(String dname) {
            this.dname = dname;
        }
    }

    2.4.创建微服务提供方

    主要思路

    引入pom依赖(调用api公共module)→  配置application.yml连接池 → 连接mysql数据库配置  → 创建并向外暴露服务接口(mapper/service/controller)

    → 启动服务检查

    ①导入依赖配置相关:

    <dependencies>
            <!--需要拿到实体类,引入api module-->
            <dependency>
                <groupId>com.fengye</groupId>
                <artifactId>springcloud-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-test</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--jetty服务器-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jetty</artifactId>
            </dependency>
            <!--热部署工具-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
        </dependencies>
    View Code

    ②yml配置:

    server:
      port: 8001
    #mybatis的配置
    mybatis:
      #config-location: classpath:mybatis/mybatis-config.xml
      type-aliases-package: com.fengye.springcloud.pojo
      mapper-locations: classpath:mybatis/mapper/*Mapper.xml
      #注意config-location: classpath:mybatis/mybatis-config.xml不能与
      #驼峰一起使用
      configuration:
        map-underscore-to-camel-case: true
    
    #spring的配置
    spring:
      application:
        name: springcloud-provider-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: org.gjt.mm.mysql.Driver
        url: jdbc:mysql://localhost:3306/springcloud_db01?useUnicode=true&characterEncoding=utf-8
        username: root
        password: admin

    ③建库、建表、mybatis操作数据库dao/service/controller一套操作CRUD这里就不多说了(有兴趣去看我的源码),主要看一下controller层暴露的服务接口:

    @RestController
    @RequestMapping("/dept")
    public class DeptController {
        @Autowired
        private DeptService service;
    
        @PostMapping("/add")
        public boolean addDept(Dept dept){
            return service.addDept(dept);
        };
    
        @GetMapping("/queryById/{id}")
        public Dept queryById(@PathVariable("id") Long id){
            return service.queryById(id);
        };
    
        @GetMapping("/queryAll")
        public List<Dept> queryAll(){
            return service.queryAll();
        };
    }

    ④测试验证服务:

    先做个小测试,看数据库连接是否成功,调用api模块是否成功。

    完美访问!

    2.5.创建微服务消费者

    主要思路

    简单依赖pom配置、开放web消费访问端口 → 基于Config创建RestTemplate Bean → 使用RestTemplate请求访问服务提供方的远程服务端口 → 测试请求访问是否成功

    ①pom依赖配置、端口开放:

     <dependencies>
            <dependency>
                <groupId>com.fengye</groupId>
                <artifactId>springcloud-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
     </dependencies>
    View Code
    server:
      port: 8002

    ②创建Config来生成RestTemplate的Bean:

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

    ③使用RestTemplate访问远端服务接口:

    @RestController
    public class DeptConsumerController {
        /**
         * 消费者:不应该有service实现层
         * RestTemplate:提供多种便捷的访问远程http服务的方法,提供简单的restful服务模板(使用简单无脑粗暴)
         * 参数类型:(url, requestMap, ResponseBean.class)分别代表REST请求地址、请求参数、HTTP响应转换被转换成的对象类型
         */
        @Autowired
        private RestTemplate restTemplate;
    
        //服务端的请求地址,这里是本机localhost,也可以是其他任意的服务机ip地址
        private static final String REST_URL_PREFIX = "http://localhost:8001";
    
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept){
            return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
        }
    
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            return restTemplate.getForObject(REST_URL_PREFIX + "/dept/queryById/" + id, Dept.class);
        }
    
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list(){
            return restTemplate.getForObject(REST_URL_PREFIX + "/dept/queryAll", List.class);
        }
    }

    ④启动请求并测试验证是否能访问成功:

    完成远端服务提供者的接口访问!

    3.总结:

    整个SpringCloud微服务是一套生态,基于SpringBoot项目的每一个服务组件(父工程管理所有子工程组件依赖及版本信息),组件之间使用HTTP协议(这里案例使用RestTemplate)进行接口调用。

    • 服务提供者提供Restful访问接口,启动服务端口,供消费者调用;
    • 服务api作为中间者,只提供服务组件(POJO),不与业务接口相耦合;
    • 服务消费者使用RestTemplate进行服务接口远程访问,直接访问远端服务接口,无脑操作;
    • 服务消费者调用远端接口后,同样使用restful接口暴露出自己的访问地址,以供服务启用显示

    最后,罗列一下本博客参考博文博主 【雨点的名字】。

    我也是她的粉丝,哈哈!这里借鉴了一下她的文章思路:基于RestTemplate微服务项目案例

     

    博客涉及代码均已上传至github:

    https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello

    写博是一种习惯,习惯坚持下去一定会有收获~  编码路漫漫,希望初心不改!就酱~

  • 相关阅读:
    Nacos 1.3.0版本部署连接mysql 8+
    Java Certificate证书问题
    UIKit之浅析UIButton
    Xcode Coule not launch "aaa" press launch failed:timed out waiting for app launch
    Cocos2d-x 安装教程for mac(Xcode)
    关于继承UITableViewController若干问题
    Table的分割线偏移量设置 及其 UIEdgeInset详解
    retain、strong、weak、assign区别
    iOS 使用xib创建cell的两种初始化方式
    No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=armv7 armv7s)
  • 原文地址:https://www.cnblogs.com/yif0118/p/14604365.html
Copyright © 2011-2022 走看看