SpringCloud简介

Spring cloud是一个基于Spring Boot实现的服务治理工具包,在微服务架构中用于管理和协调服务的
微服务:就是把一个单体项目,拆分为多个微服务,每个微服务可以独立技术选型,独立开发,独立部署,独立运维.并且多个服务相互协调,相互配合,最终完成用户的价值.
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署

springcloud组件图.png

五大重要组件

  • 服务发现——Netflix Eureka 但是目前已经停更了
  • 客服端负载均衡——Netflix Ribbon/Feign
  • 服务网关——Netflix Zuul
  • 断路器——Netflix Hystrix
  • 分布式配置——Spring Cloud Config

关于cloud升级

spring cloud升级相关-尚硅谷.png

  • 在这张图里面可以看出来Nacos很重要

注:这张图来自尚硅谷的周阳老师

  • 什么是微服务

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”(http://martinfowler.com/articles/microservices.html)。

springcloud和springboot之间的版本选择

官网:https://start.spring.io/actuator/info

我这里就直接图片spring系列版本选择.png

开始学习

从项目中学习

创建数据库

  • 先暂时创建一个支付表(payment)

    DROP TABLE IF EXISTS `payment`;
    CREATE TABLE `payment`  (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `serial` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '支付流水号',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '支付表' ROW_FORMAT = Dynamic;
    

    插入一两条数据

    insert into payment(serial) values("A10001"),values("A10002")
    
  • 打开idea 创建一个maven父工程名字("cloud2020")

    • 在父工程中不需要 src目录 所以直接删除

    • 设置整个项目的字符编码都为 utf-8 ,步骤 :File | Settings | Editor | File Encodings!image-20200320164929424.png

  • 修改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>org.example</groupId>
        <artifactId>clound2020</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <!--统一管理jar包版本-->
        <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.18.10</lombok.version>
            <mysql.version>5.1.47</mysql.version>
            <druid.version>1.1.16</druid.version>
            <mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version>
            <hutool-all.version>5.1.0</hutool-all.version>
        </properties>
    
        <!-- 子模块继承之后,提供作用:锁定版本+子模块不用写groupId和version  -->
        <dependencyManagement>
    
            <dependencies>
                <!--  springboot 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>
                <!--  springcloud 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>
                <!--  springcloud cloud alibaba 2.1.0.RELEASE    -->
                <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>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>${druid.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>${mybatis.spring.boot.version}</version>
                </dependency>
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>${log4j.version}</version>
                </dependency>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>${lombok.version}</version>
                    <optional>true</optional>
                </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>
    
  • 创建一个maven子工程(公共模块)名为(cloud-api-commons

    • 引入pom依赖

      <?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>clound2020</artifactId>
              <groupId>org.example</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>cloud-api-commons</artifactId>
          <description>公共模块</description>
      
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-devtools</artifactId>
                  <scope>runtime</scope>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>cn.hutool</groupId>
                  <artifactId>hutool-all</artifactId>
                  <version>${hutool-all.version}</version>
              </dependency>
          </dependencies>
      
      </project>
      
    • src下创建两个类分别为Payment.java(实体类)和commonsResult.java(拥有到时候返回相关信息给前端)
      Payment.java

      	@Data
          @AllArgsConstructor
          @NoArgsConstructor
          public class Payment implements Serializable {
              private Long id;
              private String serial;
          }
      

      commonsResult.java

          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          public class CommonResult<T> {
              private int    code;
              private String message;
              private T      data;
              public CommonResult(int code,String message){
                  this.code=code;
                  this.message=message;
              }
          }
      
    • 然后通过maven工具吧项目打包发布到本地仓库 ,方便以后使用,我们的公共模块暂时就算是写

    • 目录结构图:image-20200320173321160.png

  • 现在我们来创建我们的支付模块(cloud-provider-payment8001)

    • 引入pom依赖

          <dependencies>
      <!--        &lt;!&ndash;包含了sleuth+zipkin&ndash;&gt;-->
      <!--        <dependency>-->
      <!--            <groupId>org.springframework.cloud</groupId>-->
      <!--            <artifactId>spring-cloud-starter-zipkin</artifactId>-->
      <!--        </dependency>-->
      <!--&lt;!&ndash;     &ndash;&gt;-->
              <!--  eureka-client-->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
              <!--        引入公共模块-->
              <dependency>
                  <groupId>org.example</groupId>
                  <artifactId>cloud-api-commons</artifactId>
                  <version>${project.version}</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
              <!--监控-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-actuator</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.mybatis.spring.boot</groupId>
                  <artifactId>mybatis-spring-boot-starter</artifactId>
              </dependency>
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>druid-spring-boot-starter</artifactId>
                  <!--如果没写版本,从父层面找,找到了就直接用,全局统一-->
                  <version>1.1.16</version>
              </dependency>
              <!--mysql-connector-java-->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
              </dependency>
              <!--jdbc-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-jdbc</artifactId>
              </dependency>
              <!--热部署-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-devtools</artifactId>
                  <scope>runtime</scope>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
              </dependency>
          </dependencies>
      </project>
      
    • 编写 dao

      @Mapper
      public interface PaymentDao {
          public int  createPayment(Payment payment);//创建一条Payment信息
          public Payment getPaymentById(@Param("id")Long id);//根据id查询Payment信息
      }
      
    • source中创建目录为 mappermapper中创建一个PaymentMapper.xml内容如下

      <?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.hzx.springcloud.dao.PaymentDao">
          <resultMap id="BaseResultMap" type="Payment">
              <id column="id" property="id" jdbcType="BIGINT"/>
              <id column="serial" property="serial" jdbcType="VARCHAR"/>
          </resultMap>
      
          <insert id="createPayment" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
              insert into payment (serial) values (#{serial});
          </insert>
      
      
          <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
              select * from payment where id = #{id};
          </select>
      </mapper>
      
    • 编写service层(PaymentService|PaymentServiceImpl

      public interface PaymentService {
      
              /**
               * 新增
               *
               * @param payment
               * @return
               */
              int create(Payment payment);
      
              /**
               * 根据Id查询
               *
               * @param id
               * @return
               */
              Payment getPaymentById(Long id);
      
      }
      
      @Service("paymentService")
      public class PaymentServiceImpl implements PaymentService {
          @Resource
          private PaymentDao paymentDao;
      
          /**
           * 新增
           * @param payment
           * @return
           */
          @Override
          public int create(Payment payment) {
              return paymentDao.createPayment(payment);
          }
          /**
           * 根据Id查询sss
           *
           * @param id
           * @return
           */
          @Override
          public Payment getPaymentById(Long id) {
              return paymentDao.getPaymentById(id);
          }
      }
      
    • 编写控制层(controller

      @Controller
      @Slf4j
      public class PaymentController {
          @Resource
          private PaymentService paymentService;
      
          @PostMapping(value = "/payment/create")
          @ResponseBody
          public CommonResult<Payment> create(@RequestBody Payment payment){
      
              int result=paymentService.create(payment);
              log.debug("******插入结果:"+result);
              if (result>0){
                  return new CommonResult(200,"插入数据库成功 ",result);
              }
              return new CommonResult(444,"插入数据库失败",null);
          }
      
          @GetMapping(value = "/payment/get/{id}")
          @ResponseBody
          public CommonResult getPaymentById(@PathVariable("id")Long id){
              Payment payment=paymentService.getPaymentById(id);
              log.debug("******查询结果:"+payment);
      
              if (payment !=null){
                  return new CommonResult(200,"查询成功",payment);
              }
              return new CommonResult(444,"没有对应数据",null);
      
          }
      }
      
  • 最基础的项目创好了,来测试一下 访问

    分别访问(因为我们有些事post的所用我们用工具postman来进行测试)

    http://localhost:8001/payment/create?serial=A0002

    image-20200320180742855.png

    http://localhost:8001/payment/get/44

    image-20200320180524904.png

  • 上面测试都没有问题就,开始创建订单消费者模块cloud-consumer-order80

    • 引入pom依赖

          <dependencies>
              <!--包含了sleuth+zipkin-->
      <!--        <dependency>-->
      <!--            <groupId>org.springframework.cloud</groupId>-->
      <!--            <artifactId>spring-cloud-starter-zipkin</artifactId>-->
      <!--        </dependency>-->
      <!--        引入公共模块-->
              <dependency>
                  <groupId>org.example</groupId>
                  <artifactId>cloud-api-commons</artifactId>
                  <version>${project.version}</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
      
              <!--监控-->
      <!--        <dependency>-->
      <!--            <groupId>org.springframework.boot</groupId>-->
      <!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
      <!--        </dependency>-->
              <!--eureka client-->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
              <!--热部署-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-devtools</artifactId>
                  <scope>runtime</scope>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.example</groupId>
                  <artifactId>cloud-api-commons</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <scope>compile</scope>
              </dependency>
          </dependencies>
      
      </project>
      
    • 编写application.yml修改端口

      spring:
        application:
          name: cloud-consumer-service  #服务名
      
      server:
        port: 80    
      
      
    • 因为我们现在要写微服务项目工程所以我们要用到RestTmplate 所以创建一个config目录然后创建一个applicationConfig

      @Bean
      public RestTemplate getRestTemplate(){
          return new RestTemplate();
      }
      
    • 开始写controller层 创建一个名为 OrderControler的java类

      @RestController
      @Slf4j
      public class OrderController {
          @Resource
          private RestTemplate getRestTemplate;
          //先暂时固定
         private static final String PAYMENT_URL="http://localhost:8001";
      
      
          /**
           * http://localhost/consumer/payment/create
           * @param payment
           * @return
           */
          @GetMapping("/consumer/payment/create")
          public CommonResult<Payment> create(Payment payment) {
              return getRestTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
          }
          /**
           * http://localhost/consumer/payment/get/31
           *
           * @param id
           * @return
           */
          @GetMapping("/consumer/payment/get/{id}")
          public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
              return getRestTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
          }
      }
      

      测了成功我们的项目最简单的搭建就完了

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

只有不断的努力才会有更大的惊喜等着你去发现!!