• 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注解)
  • 相关阅读:
    java中几个常见的Arrays下的类
    java二分查找法的实现过程
    java冒泡排序的实现过程
    java数组中选择排序的实现
    正则表达式
    StringBuilder的使用与总结
    String的几个常用API
    关于API,注释文档以及String
    关于sqlserve2000和sqlserver2005以后版本配置连接池的一些思路
    专题-X教育
  • 原文地址:https://www.cnblogs.com/binwenhome/p/13172163.html
Copyright © 2020-2023  润新知