springcloud-基础入门(一)

微服务架构概述

  1. 微服务架构是一种架构模式, 它提倡将单一应用划分为一组小的服务, 服务之间相互协调, 相互配合.
  2. 每个服务运行在其独立的进程中, 服务与服务之间采用轻量级的通信机制互相协作(通常是基于HTTP协议的REST)
  3. 每个服务都围绕着具体业务进行构建, 并且能够被独立的部署到生产环境, 类生产环境等.
  4. 此外, 应当避免统一的, 集中式的服务管理机制, 对一个具体的服务而言, 应根据上下文, 选择合适的语言, 工具进行构建
  5. 基于分布式的微服务架构
    • 服务注册与发现
    • 服务调用
    • 服务熔断
    • 负载均衡
    • 服务降级
    • 服务消息队列
    • 配置中心管理
    • 服务网关
    • 服务监控
    • 全链路追踪
    • 自动化构建部署
    • 服务定时任务调度操作

SpringCloud简介

  • 是什么
  1. SpringCloud = 分布式微服务架构的一站式解决方案, 是多种微服务架构落地技术的集合体, 俗称微服务全家桶.
  • SpringCloud技术栈
    1. 服务注册发现 - Eureka
    2. 服务负载与调用 - Ribbon/Feign
    3. 服务熔断降级 - Hystrix
    4. 服务网关 - Zuul
    5. 服务配分布式配置 - SpringCloud Config
    6. 服务开发 - SpringBoot

版本的选择

  1. SpringBoot和SpringCloud版本选择
  2. 具体的选择

关于Cloud各种组件的停更/升级/替换

  • 停更
  1. 停止更新, 但仍然可以使用.
    • 被动修复bugs
    • 不再接收和并请求
    • 不再发布新版本
  • Cloud的升级

订单-支付模块微服务

总父工程

  • 搭建总的聚合父工程
  1. 创建一个maven工程: cloud2020
    • 创建时勾选
  2. 注意
    • 若创建完后报错
      <reporting>
              <plugins>
                  <plugin>
                      <artifactId>maven-project-info-reports-plugin</artifactId>
                  </plugin>
              </plugins>
      </reporting>
    • 是因为缺少依赖, 加上即可
      <dependency>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
      </dependency>
  • 父工程pom文件
  1. 添加packaging: 总的父工程
    <packaging>pom</packaging>
  2. 管理各种依赖和插件
    <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>
            <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>
    
        <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version  -->
        <dependencyManagement>
            <dependencies>
                <!--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 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>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>${log4j.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>
    • dependencyManagement来提供一种管理依赖版本号的方式
      • 该标签一般只在父工程中出现.
      • 之后在子项目中就不用写version了, 版本和它保持一致.
      • 它只确定规范, 并不引入具体的jar包.
  3. maven中跳过单元测试, 节约时间
  4. 父工程创建完后执行mvn:install将父工程发布到仓库方便子工程继承.

 Rest微服务工程构建(支付模块)

  • 工程结构
  • 如何构建微服务模块
    • 建子module: cloud-provider-payment8001
    • 改POM
      <dependencies>
          <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>
          </dependency>
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
          </dependency>
          <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>
    • 写yml
      server:
        port: 8001
      
      spring:
        application:
          name: cloud-payment-service
        datasource:
          type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
          driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
          url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false    
      username: root password: root mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: springcloud.entities # 所有entity实体类所在包
    • 主启动
      @SpringBootApplication
      public class PaymentMain8001 {
      
          public static void main(String[] args) {
              SpringApplication.run(PaymentMain8001.class, args);
          }
      }
  1. 业务类: (controller - service - dao - mysql)  ->  Json串
    • 建表SQL
      CREATE TABLE payment(
          id BIGINT(20) PRIMARY KEY AUTO_INCREMENT,
          `serial` VARCHAR(200) DEFAULT ''
      );
    • 创建entities
      • Payment
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public class Payment implements Serializable {
        
            private Long id;
            private String serial;
        }
      • json封装体CommonResult (前后端分离模式下, 后端只往前端传json串)
        //返回通用的json实体串
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public class CommonResult<T> {
        
            private Integer code;
            private String message;
            private T data;
        
            public CommonResult(Integer code, String message) {
                this(code, message, null);
            }
        }
    •  dao
      • 接口PaymentDao
        @Mapper
        public interface PaymentDao {
        
            public int create(Payment payment);
        
            public Payment getPaymentById(@Param("id") Long id);
        }
      • mybatis的映射文件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="springcloud.dao.PaymentDao">
        
            <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
                insert into payment(serial) values(#{serial});
            </insert>
        
            <resultMap id="BaseResultMap" type="springcloud.entities.Payment">
                <id column="id" property="id" jdbcType="BIGINT" />
                <id column="serial" property="serial" jdbcType="VARCHAR"/>
            </resultMap>
            <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
                select * from payment where id = #{id}
            </select>
        
        </mapper>
    • service
      • 接口PaymentService
        public interface PaymentService {
        
            public int create(Payment payment);
        
            public Payment getPaymentById(@Param("id") Long id);
        }
      • 实现类
        @Service
        public class PaymentServiceImpl implements PaymentService {
        
            @Resource
            private PaymentDao paymentDao;
        
        
            @Override
            public int create(Payment payment) {
                return paymentDao.create(payment);
            }
        
            @Override
            public Payment getPaymentById(Long id) {
                return paymentDao.getPaymentById(id);
            }
        }
    • controller
      @RestController
      @Slf4j
      public class PaymentController {
      
          @Resource
          private PaymentService paymentService;
      
          @PostMapping(value = "/payment/create")
          public CommonResult create(@RequestBody Payment payment) {
              int result = paymentService.create(payment);
              log.info("插入结果: " + result);
      
              if (result > 0) {
                  return new CommonResult(200, "插入数据库成功", result);
              }
              return new CommonResult(444, "插入数据库失败");
          }
      
          @GetMapping(value = "/payment/get/{id}")
          public CommonResult getPaymentById(@PathVariable("id") Long id) {
              Payment payment = paymentService.getPaymentById(id);
              log.info("插入结果: " + payment);
      
              if (payment != null) {
                  return new CommonResult(200, "查询成功", payment);
              }
              return new CommonResult(444, "没有对应记录, 查询ID:" + id);
          }
      }
  2. 测试 - 使用Postman工具
    • 测试插入: POST请求 - http://localhost:8001/payment/create?serial=T-46
    • 测试查询: GET请求 - http://localhost:8001/payment/get/1

热部署Devtools

  •  即代码改了以后, 可以自动重启服务器, 而不用手动重启.
  1. 添加依赖
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
  2. 添加插件
    <!-- 在父工程中添加 -->
        <build>
            <finalName>cloud2020</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <fork>true</fork>
                        <addResources>true</addResources>
                    </configuration>
                </plugin>
            </plugins>
        </build>
  3. 开启自动编译的权限
  4. 更新值
    • 在pom文件中 ctrl+alt+shift+/ -> Registry.. , 勾选如下两个选项
  5. 重启IDEA
  • 注意: 只在开发阶段使用项目热部署, 发布时必须关闭.

 微服务消费者订单Module模块

  • RestTemplate
    • RestTemplate提供了多种便捷访问远程Http服务器的方法, 是一种简单便捷的访问restful服务模板类, 是Spring提供的用于访问Rest服务的客户端模板工具集.
    • 使用时很简单
      (url, requestMap, ResponseBean.class)
      三个参数分别代表REST请求地址, 请求参数, HTTP响应转换被转成的对象类型.
  1.  建module
  2. 改pom
    <dependencies>
            <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.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>
  3. 写yml
    server:
      port: 80 # 浏览网页服务默认端口80
  4. 主启动
  5. 业务类
    • entities: 同上
    • config
      @Configuration
      public class ApplicationContextConfig {
      
          @Bean
          public RestTemplate getRestTemplate() {
              return new RestTemplate();
          }
      }
    • OrderController
      @RestController
      @Slf4j
      public class OrderController {
      
          private static final String PAYMENT_URL = "http://localhost:8001";
      
          @Resource
          private RestTemplate restTemplate;
      
          //浏览器只能发get请求, 但下面调用的实质是post请求
          @GetMapping("/consumer/payment/create")
          public CommonResult<Payment> create(Payment payment) {
      
              log.info(payment.toString());
              String url = PAYMENT_URL + "/payment/create";
              return restTemplate.postForObject(url, payment, CommonResult.class);
          }
      
          @GetMapping("/consumer/payment/get/{id}")
          public CommonResult<Payment> getPayment(@PathVariable("id")Long id) {
      
              String url = PAYMENT_URL + "/payment/get/" + id;
              return restTemplate.getForObject(url, CommonResult.class);
          }
      }
    • 测试
      • 查询: GET请求 - http://localhost/consumer/payment/get/1
      •  插入: Get请求 - http://localhost/consumer/payment/create?serial=T-51  (不要忘记在支付模块中加入@RequestBody注解)

猜你喜欢

转载自www.cnblogs.com/binwenhome/p/13172163.html