第一章 SpringCloud介绍及微服务架构编码构建

  • Post author:
  • Post category:其他





尚硅谷SpringCloud框架开发教程(SpringCloudAlibaba微服务分布式架构丨Spring Cloud)_哔哩哔哩_bilibili



https://www.bilibili.com/video/BV18E411x7eT/?spm_id_from=333.337.search-card.all.click



1. 微服务架构概述


微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。

每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful AP)。每个服务都围绕着具本业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的个服务而善应根据业务上下文,选择合适的语言、工具对其进行构建。


微服务技术栈

:服务集群、注册中心、配置中心(热更新)、服务网关(校验、路由、负载均衡)、分布式缓存、分布式搜索、消息队列(异步通信)、数据库集群、分布式日志、系统监控链路追踪。


单体架构

:将业务的所有的功能模块集中到一个项目中开发,打包成一个包部署。

优点:

架构简单、部署成本低;

缺点:

耦合度高 图片地址:



XX系统架构图 流程图模板_ProcessOn思维导图、流程图



https://www.processon.com/view/643bcd5f6dcb245472aae47a?fromnew=1



分布式架构

:根据业务功能对系统进行拆分,每一页五五模块作为独立项目开发,称为一个服务。

优点:

降低服务耦合,有利于服务升级拓展;

缺点:

架构非常负载,运维、监控、部署难度提高。

2. Spring Cloud简介


SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶。

Spring Cloud就是为开发人员所提供的一套快速构建的分布式系统工具。对于单体架构和分布式架构可以这么理解,单体架构对于Java开发人员可以说就是一个单体Spring Boot框架搭建的系统,而对于分布式架构如果使用微服务方式实现就是多个Spring Boot开发的服务集形成的系统。因此Spring Cloud相比于Spring Boot不在注重服务本身的开发而是服务集管理。

3. Spring Cloud技术栈

图片地址:



Spring Cloud 微服务总体架构图 流程图模板_ProcessOn思维导图、流程图



https://www.processon.com/view/64219530e9cb570f835d0326?fromnew=1


  • SpringCloud:注册中心(Eureka、Consul)、服务远程调用(Fegin–http协议)、配置中心(Spring Cloud Config)、服务网关(Spring Cloud Gateway、Zuul)、服务监控和保护(Hystrix)

  • Spring Cloud Alibaba:注册中心(Nacos、Eureka)、服务远程调用(Dubbo、Fegin)、配置中心(Spring Cloud Config、Nacos)、服务网关(Spring Cloud Gateway、Zuul)、服务监控和保护(Sentinel)

4. Spring Cloud与Spring Boot版本依赖

Spring Boot在git源代码地址:

https://github.com/spring-projects/spring-boot/releases

Spring Boot2.0新特性:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes

Spring Boot官网:

Spring Boot

Spring Cloud在git源代码地址:

https://github.com/spring-projects/spring-cloud

Spring Cloud官网:

Spring Cloud


Spring Cloud与Spring Boot版本选择:

1.进入官网:

Spring Cloud

第一步:

第二步:

2.进入

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

,筛选版本(对于json数据格式,可以使用tool.lu在线工具)

3.进入Spring Cloud官网滑到中底部


停更不停用

: 被动修复bugs、不再接受和并请求、不在发布新版本

服务注册中心:Eureka(停更不停用)\Zookeeper\Consul\Nacos 服务调用:Ribbon\LoadBalancer\Feign(死了)\OpenFeign 服务降级:Hystrix(死了)\resilience4j\sentinel 服务网关:Zuul(死了)\gateway 服务配置:Config(不使用)\Nacos 服务总线:Bus(不使用)\Nacos

5. 微服务服务架构搭建


技术和工具版本选型

:spring cloud(Hoxton.SR1)、spring boot(2.2.2.RELEASE)、cloud alibaba(2.1.0.RELESE)、Java(8)、Maven(3.5以上)、MySQL(5.7以上)

5.1 搭建父工程

搭建父工程目的是为了规范jar的版本,对于整个微服务来说使用相同版本的jar包实现版本统一或者减少子项目多次输入jar包版本。

这里详细展示需要注意搭建一个项目工程步骤,后续省略: 1.New Project中(选择一个最小)

2.字符编码(setting->file encoding)

3.注解激活

4.Java编译版本

5.文件过滤

5.2 父工程pom
<groupId>com.yicai.springcloud</groupId>
  <artifactId>cloud2020</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--  表示pom总的父工程-->
  <packaging>pom</packaging>
​
  <!--统一jar和版本号管理-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compailer.target>1.8</maven.compailer.target>
    <junit.version>4.12</junit.version>
    <log4j.version>1.2.17</log4j.version>
    <lombok.version>1.18.24</lombok.version>
    <mysql.version>5.1.47</mysql.version>
    <druid.version>1.2.8</druid.version>
    <mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version>
  </properties>
​
  <!--  子模块继承之后,提供作用:锁定版本+子module不写groupId和version-->
  <!--  父pom的依赖管理,子项目不用引入版本号,Maven会沿着父子层次向上爬,直到有个dependencyManagement  -->
  <dependencyManagement>
    <dependencies>
      <!--      Spring Boot版本-->
      <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版本-->
      <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-->
      <!-- spring cloud alibaba 2.1.0.RELEASE  关于依赖来取问题:https://blog.csdn.net/xxly1994/article/details/107058474-->
      <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>
      </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>
      <!--      lombok-->
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
​
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>2.2.5.RELEASE</version>
        <configuration>
          <fork>true</fork>
          <addResources>true</addResources>
        </configuration>
      </plugin>
    </plugins>
  </build>


Maven中dependencyManagement与depency

Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个dependencyManagement 元素中指定的版本号。 ​

dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖

。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且

version和scope都读取自父pom

。如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。


Maven中跳过单元测试

5.3 Rest微服务工程构建


1.构建cloud-provider-payment8001

pom文件:

<dependencies>
<!--        spring-boot-web 启动类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        spring-boot-actuator 健康监控-->
        <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>
<!--        druid基于spring-boot-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <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>

application.yaml

#端口
server:
  port: 8001
  
spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.25.153:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: Mya_123456
​
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities

主启动类:

@SpringBootApplication
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}

业务类:


Linux安装MySQL数据库

  1. 建表

create table `payment`(
    `id` bigint(20) not null auto_increment comment 'ID',
    `serial` varcahr(200) default '',
    primary key(`id`)
)engine=innodb auto_increment=1 default charset=utf8;
  1. entities

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {  //序列化
    private Long id;
    private String serial;
}
  1. dao

@Mapper
public interface PaymentDao {
    //新增
    int create(Payment payment);
    //读取
    Payment getPaymentById(@Param("id") Long id);
}
<mapper namespace="com.yicai.springcloud.dao.PaymentDao">

    <insert id="create" parameterType="com.yicai.springcloud.entities.Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) value(#{serial})
    </insert>

    <resultMap id="BaseResultMap" type="com.yicai.springcloud.entities.Payment">
        <id property="id" column="id" jdbcType="BIGINT"></id>
        <id property="serial" column="serial" jdbcType="VARCHAR"></id>
    </resultMap>

    <select id="getPaymentById" resultMap="BaseResultMap" parameterType="Long">
        select * from payment where id=#{id}
    </select>
    
</mapper>
  1. service

public interface PaymentService {
    //新增
    int create(Payment payment);
    //读取
    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);
    }
}
  1. controller

@RestController
@Slf4j
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @PostMapping(value = "/payment/create")
    public CommonResult create(Payment payment){
        int result= paymentService.create(payment);
        log.info("*********插入结果:"+result);
        if(result>0){
            return new CommonResult(200,"插入成功",result);
        }else {
            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);
        }else {
            return new CommonResult(444,"没有");
        }
    }
}
  1. 测试


2.构建cloud-consumer-order80

pom文件:

<dependencies>
        <!--        spring-boot-web 启动类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        spring-boot-actuator 健康监控-->
        <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>

application.yaml:

server:
  port: 80

主启动类:

@SpringBootApplication
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

业务层:

  1. 实体类:跟colud-provider-payment8001项目一样

  2. 使用RestTemplate,配置RestTempalte

@Configuration
public class ApplicationContextConfig {
    
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
  1. controller

@RestController
@Slf4j
public class OrderController {

    public static final String PAYMENT_URL="http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }
}
  1. 测试



添加注解@RequestBody解决此类问题。




RestTemplate

:RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集。 官网:

https://docs.spring.io/spring-framewprk/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

快捷方式:

  1. 热部署(生产不建议)

  2. RunDashboard


3.工程重构

工程重构:主要就是将相同代码部分组成一个module项目,将module项目打成jar的方式,在其他项目中引入,解决代码冗余。

创建cloud-api-commons模块:

pom文件:

<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>5.8.6</version>
        </dependency>
    </dependencies>

entities:跟colud-provider-payment8001项目一样

cloud-api-commons项目clean和install,其他模块并引入jar包:

<dependency>
    <groupId>com.yicai.springcloud</groupId>
    <artifactId>cloud-api-commons</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

测试:

gitee源代码地址:

springcloud_study: springcloud:服务集群、注册中心、配置中心(热更新)、服务网关(校验、路由、负载均衡)、分布式缓存、分布式搜索、消息队列(异步通信)、数据库集群、分布式日志、系统监控链路追踪。



版权声明:本文为qq_53957101原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。