美文网首页SpringCloud微服务Spring Cloud
SpringCloud(一)-手把手教你创建springclou

SpringCloud(一)-手把手教你创建springclou

作者: Renaissance_ | 来源:发表于2020-05-28 19:10 被阅读0次

    现在微服务思想大行其道,各个公司都在如火如荼的进行技术转型,掌握SpringCloud已经成为升职加薪的垫脚石,笔者将从本文开始从实战和原理记录SpringCloud的学习过程。

    系列文章
    SpringCloud(一)-手把手教你创建springcloud微服务父子项目
    SpringCloud(二)-手把手教你搭建Eureka Server和Eureka Client
    SpringCloud(三)-手把手教你通过Rinbbon实现客户端负载均衡
    SpringCloud(四)-手把手教你使用OpenFeign
    SpringCloud(五)-手把手教你使用Hystrix配置服务熔断和降级以及Hystrix Dashboard
    SpringCloud(六)-手把手教你搭建SpringCloud Config配置中心
    SpringCloud(七)-手把手教你使用消息总线Bus实现动态刷新
    SpringCloud(八)-手把手教你使用Stream消息驱动

    码云地址

    https://gitee.com/zhaowenyi/springcloudtest/tree/master

    初识SpringCloud

    打开SpingCloud中文官网,一行"微服务集大成者,云计算最佳业务实践"赫然入目,由此可知SpringCloud在微服务领域的影响力。

    SpringCloud 是由一系列技术栈组合而成:

    • Spring Cloud Config: 管理配置包,可以将配置文件放在远程服务器上集中化管理集群配置文件。支持本地存储,git,subversion。
    • Spring Cloud Bus:事件、消息总线,可以在集群中传播状态变化,比如配置文件变动,可以和Spring Cloud Config组合使用。
    • Netflix Eureka:服务注册与发现,一个基于REST服务,用于服务注册与发现,故障转移等功能
    • Netflix Hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而为延迟和故障提供更强大的容错能力。
    • Netflix Zuul:提供动态路由,监控和安全等边缘服务的框架。
    • Netflix Ribbon:提供云端负载均衡,有多种负载均衡可供选择,可和熔断器和服务发现组合使用
    • Open Feign: 是一款申明式,模块化的HTTP客户端

    这还只是列出的一部分常用的框架,还有很多都没有列出来,光通过定义都难以理解这些框架是干什么用的,只能千里之行始于足下,一步步开始攻克这些知识点了。

    初识SpringBoot

    上面的框架中没有列出SpringBoot,是因为SpringBoot作为最基础的框架,是基石,任何微服务都要从搭建一个Spring Boot项目开始。

    那么什么是Spring Boot呢?

    打开Spring Boot官网,我们了解到
    使用Spring Boot可以轻松地创建独立的,基于生产级别的基于Spring的应用程序,我们可以“运行”它们。也就是Spring Boot帮我们配置了Spring 项目中哪些繁琐的配置,而且内置了服务器,比如tomcat,我们可以直接运行它。

    总之其Spring思想还是没有变,只是帮我们简单快速的搭建一个Spring 项目。

    构建SpringCloud项目

    接下来就是开始搭建SpringCloud项目了。首选我们要搭建Spring Cloud项目父工程。

    工具准备

    • JDK : 1.8
    • Spring Boot:2.0
    • IntelliJ IDEA:ULTIMATE 2017.02
    • Mysql:5.6.24
    • Win10
    • Maven: 3.6

    搭建步骤

    创建父工程
    新建项目 输入gav坐标 选择项目路径.png

    点击File - settings - Build Tools - Maven ,这里的Maven路径选择自己本地的maven路径。

    设置maven路径

    设置自动导入依赖

    点击Enable Auto Import

    Editor - File Types,末尾加上“.idea;.iml;”,设置隐藏impl文件和.idea文件

    image.png

    File - settings - Build - Complier - Java Complier ,需要将编译版本设置为1.8

    设置编译的jdk版本

    最终的项目结构

    项目结构

    pom.xml加入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.elio.springcloud</groupId>
        <artifactId>springcloudtest</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <!--统一管理jar包版本-->
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <junit.version>4.12</junit.version>
            <lombok.version>1.18.10</lombok.version>
            <log4j.version>1.2.17</log4j.version>
            <mysql.version>5.1.47</mysql.version>
            <druid.version>1.1.16</druid.version>
            <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
        </properties>
    
        <!--子模块继承之后,提供作用:锁定版本+子module不用写groupId和version-->
        <dependencyManagement><!--定义规范,但不导入-->
            <dependencies>
                <dependency>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </dependency>
                <!--spring boot 2.2.2-->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>2.2.2.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--spring cloud Hoxton.SR1-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Hoxton.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--spring cloud 阿里巴巴-->
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>2.1.0.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--mysql-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                    <scope>runtime</scope>
                </dependency>
                <!-- druid-->
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>${druid.version}</version>
                </dependency>
                <!--mybatis-->
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>${mybatis.spring.boot.version}</version>
                </dependency>
                <!--junit-->
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
                <!--log4j-->
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>${log4j.version}</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <!--热启动插件-->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <fork>true</fork>
                        <addResources>true</addResources>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
    创建子工程

    父工程完成后,我们接下来创建两个子项目,一个是商品服务的提供者,一个是商品服务的消费者。首先来创建商品服务的提供者

    右键项目名,点击New - module

    新增子项目 点击next

    输入子项目名称 ”springcloud-product-provider-8100“,表示的商品的提供者,使用8100端口

    输入子项目名称 点击next

    点击finish后,我们可以看到构建成功的子项目

    商品服务提供者8100

    添加商品服务提供者的pom.xml配置

    右键商品服务提供者项目的resources文件夹,新增application.yml配置文件,新增之后application.yml前面有个绿色的小叶子标识

    新增yml配置文件

    yml中的配置文件如下

    server:
      port: 8100 #端口号
    
    spring:
      application:
        name: springcloud-product-provider-8100
      datasource:
          url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&userSSL=false
          driverClassName: com.mysql.jdbc.Driver
          username: root
          password: 111111
    
    mybatis:
      mapper-locations: classpath:mapping/*mapper.xml # Mybatis 映射文件位置
      type-aliases-package: com.elio.springcloud.entity  # 表对应的实体类包
    
    
    

    右键java文件夹新增,实体类Product,这将是我们接下来的product表对应的实体类

    package com.elio.springcloud.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    @NoArgsConstructor
    @AllArgsConstructor
    @Setter
    @Getter
    public class Product {
    
        private Long id; //自增id
        private String name;// 产品名称
        private int stock;// 库存
    
    }
    
    

    新增dao层接口ProductMapper

    package com.elio.springcloud.dao;
    
    import com.elio.springcloud.entity.Product;
    import org.apache.ibatis.annotations.Param;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface ProductMapper {
        /**
         * 查询
         * @param id
         * @return
         */
        public Product selectById(@Param("id") Long id);
    
    
        /**
         * 删除
         * @param id
         * @return
         */
        public int deleteById(@Param("id") Long id);
    
        /**
         * 修改
         * @param id
         * @param name
         * @return
         */
        public int updateById(@Param("id") Long id, @Param("name") String name);
    
        /**
         * 新增
         * @param product
         * @return
         */
        public int insertOne(Product product);
    }
    
    

    右键resources文件,新增mapping\product_mapper.xml文件,这个是product表对应的sql文件,包含简单的增删改查

    <?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.elio.springcloud.dao.ProductMapper">
    
        <resultMap id="BaseResultMap" type="com.elio.springcloud.entity.Product">
            <result column="id" jdbcType="BIGINT" property="id" />
            <result column="name" jdbcType="VARCHAR" property="name" />
            <result column="stock" jdbcType="INTEGER" property="stock" />
        </resultMap>
    
        <!--查询-->
        <select id="selectById" resultType="Product">
            select * from product where id = #{id}
        </select>
    
        <!--删除-->
        <delete id="deleteById" parameterType="Long">
            delete from product where id = #{id}
        </delete>
    
        <!--修改-->
        <update id="updateById" parameterType="Product">
            update product set name = #{name} where id = #{id}
        </update>
    
        <!--新增-->
        <insert id="insertOne" parameterType="Product">
           insert into product(name, stock) values (#{name}, #{stock})
        </insert>
    
    </mapper>
    
    

    新增ProductService.java文件

    package com.elio.springcloud.service;
    
    import com.elio.springcloud.entity.Product;
    import org.apache.ibatis.annotations.Param;
    
    /**
     * 商品服务类
     */
    public interface ProductService {
    
        /**
         * 查询
         * @param id
         * @return
         */
        public Product selectById(Long id);
    
    
        /**
         * 删除
         * @param id
         * @return
         */
        public int deleteById(Long id);
    
        /**
         * 修改
         * @param id
         * @param name
         * @return
         */
        public int updateById(Long id, String name);
    
        /**
         * 新增
         * @param product
         * @return
         */
        public int insertOne(Product product);
    
    }
    
    
    

    新增ProductServiceImpl.java 类

    package com.elio.springcloud.service.impl;
    
    import com.elio.springcloud.dao.ProductMapper;
    import com.elio.springcloud.entity.Product;
    import com.elio.springcloud.service.ProductService;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    @Service
    public class ProductServiceImpl implements ProductService{
    
        @Resource
        private ProductMapper productMapper;
    
        public Product selectById(Long id) {
            return productMapper.selectById(id);
        }
    
        public int deleteById(Long id) {
            return productMapper.deleteById(id);
        }
    
        public int updateById(Long id, String name) {
            return productMapper.updateById(id, name);
        }
    
        public int insertOne(Product product) {
            return productMapper.insertOne(product);
        }
    }
    
    
    

    新增Result.java

    package com.elio.springcloud.dto;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    @AllArgsConstructor
    @NoArgsConstructor
    @Setter
    @Getter
    public class Result {
    
        private int code;
        private String message;
        private Object result;
    }
    
    

    新增ProductProviderController.java

    package com.elio.springcloud.controller;
    
    import com.elio.springcloud.dto.Result;
    import com.elio.springcloud.entity.Product;
    import com.elio.springcloud.service.ProductService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.*;
    
    import javax.annotation.Resource;
    
    @RestController
    @Slf4j
    @RequestMapping("/")
    public class ProductProviderController {
    
        @Resource
        private ProductService productService;
    
        /**
         * 查询
         * @param id
         * @return
         */
        @GetMapping("product/provider/get/{id}")
        public Result selectById(@PathVariable("id") Long id){
            return new Result(200, "查询成功", productService.selectById(id));
        }
    
        /**
         * 删除
         * @param id
         * @return
         */
        @GetMapping("product/provider/delete/{id}")
        public Result deleteById(@PathVariable("id") Long id){
            return new Result(200, "删除成功", productService.deleteById(id));
        }
    
        /**
         * 修改
         * @param product
         * @return
         */
        @PostMapping("product/provider/update")
        public Result updateById(@RequestBody Product product){
            return new Result(200, "修改成功", productService.updateById(product.getId(), product.getName()));
    
        }
    
        /**
         * 新增
         * @return
         */
        @PutMapping( "product/provider/add")
        public Result insertById(@RequestBody Product product){
            return new Result(200, "修改成功", productService.insertOne(product));
        }
    }
    
    

    右键java文件夹,新增主启动类ProductProvider8100

    新增主启动类

    ProductProvider8100内容如下,加上@SpringBootApplication和MapperScan注解

    package com.elio.springcloud;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @MapperScan("com.elio.springcloud.dao")
    public class ProductProvider8100 {
    
        public static void main(String[] args){
            SpringApplication.run(ProductProvider8100.class, args);
        }
    }
    
    
    

    创建表结构

    
    -- ----------------------------
    -- Table structure for product
    -- ----------------------------
    DROP TABLE IF EXISTS `product`;
    CREATE TABLE `product` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `stock` int(10) unsigned DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    
    

    测试

    至此微服务的商品提供者,我们已经创建成功,接下来就是测试该提供者了


    右键主启动类DEBUG

    启动成功后可以查看结果如下


    启动成功

    浏览器地址输入 http://localhost:8100/product/provider/get/1

    查询结果
    创建商品服务消费者

    右键父项目,点击next

    点击Next 输入项目名 输入项目名

    配置商品消费者的pom.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>springcloudtest</artifactId>
            <groupId>com.elio.springcloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>springcloud-product-consumer-8200</artifactId>
    
    
        <dependencies>
            <!--spring boot -->
            <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>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    
        <!--热启动插件-->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <fork>true</fork>
                        <addResources>true</addResources>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    resources文件夹下新增application.yml文件

    server:
      port: 8200
    
    spring:
      application:
        name: springcloud-product-consumer-8200
    
    

    新增主启动类 ProductConsumer8200,因为消费者不需要连接数据库,所以pom.xml中也没有导入相关依赖,因此需要将自动注入数据源的的类过滤掉 @SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})

    package com.elio.springcloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
    import org.springframework.context.annotation.ComponentScan;
    
    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
    public class ProductConsumer8200 {
    
        public static void main(String[] args){
            SpringApplication.run(ProductConsumer8200.class, args);
        }
    }
    
    

    新增业务类 ProductConsumerController

    package com.elio.springcloud.controller;
    
    import com.elio.springcloud.dto.Result;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import javax.annotation.Resource;
    
    @RestController
    public class ProductConsumerController {
    
        @Resource
        RestTemplate restTemplate;
    
        public static String url = "http://localhost:8100/";
    
        /**
         * 查询
         * @param id
         * @return
         */
        @GetMapping("product/consumer/get/{id}")
        public Result selectById(@PathVariable("id") Long id){
    
            return new Result(200, "查询成功",
                    restTemplate.getForObject(url+"product/provider/get/"+id, Result.class));
        }
    
    }
    
    

    **新增结果返回实体类Result **

    package com.elio.springcloud.dto;
    
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    @AllArgsConstructor
    @NoArgsConstructor
    @Setter
    @Getter
    public class Result {
    
        private int code;
        private String message;
        private Object result;
    }
    
    

    因为要调用消费者的api, 因此我们需要注入restTemplate对象,新增RestConfig

    package com.elio.springcloud.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class RestConfig {
    
        @Bean
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    }
    
    

    至此,我们已经创建好了消费者项目,接下来就是测试了

    消费者项目架构

    右键主启动类,启动成功后会显示如下结果

    启动日志

    浏览器地址输入 http://localhost:8200/product/consumer/get/1
    这是使用消费者的路径访问提供者的api,结果如下

    返回成功的结果

    总结

    我们至此创建了一个父项目springcloudtest,然后有一个商品服务提供者
    springcloud-product-provider-8100 和一个商品服务消费者springcloud-product-consumer-8200 。然后这就是最简单的两个微服务了,实现了功能的解耦,但是这个简单的微服务存在着很多问题,比如都用公共的实体类Result,还有提供者地址在消费者里面写死了等等,这些问题,我们接下来会一一解决。如有问题,请在评论区指正。

    项目架构

    相关文章

      网友评论

        本文标题:SpringCloud(一)-手把手教你创建springclou

        本文链接:https://www.haomeiwen.com/subject/yzlaahtx.html