SpringCloud简介、入门案例

SpringCloud简介

SpringCloud是一系列框架的有序集合,它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用SpringBoot的开发风格做到一键启动和部署。SpringCloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过SpringBoot风格进行再封装屏,蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

详细介绍: https://baike.so.com/doc/25751000-26884657.html

配套参考资料:

springcloud项目官方主页:https://projects.spring.io/spring-cloud

springcloud中文网(有很详细的翻译文档):https://springcloud.cc

springcloud中文论坛:http://springcloud.cn

SpringCloud入门案例(使用的是jpa)

使用SpringBoot开发项目的好处在于能够快速的开发单体项目,很多框架整合无需配置,极大的提高了开发效率。使用SpringBoot开发项目依然属于传统的开发模式,因为所有的代码都写在一个工程内。

Mvc模式相信已经被大家所熟知,Mvc模式是为了使代码层次分明,便于维护,提高代码的健壮性;当项目过于臃肿的话,MVC模式的项目依然难于维护。而SpringCloud作为分布式服务技术的代表,其实就是对MVC模式的一种延伸。将整个项目的model层、dao层、service层、controller层等等进行拆分,使其独立出来成为一个单独的项目,解决由于项目过于臃肿不便于维护所带来的一系列问题。

最简单的微服务架构会有四个工程:

父工程:microservice(主要就是一个pom,用于管理module,以及管理依赖,规范所有jar包版本等

通用模块(M):microservice-common(主要是放一些其他项目公用的东西,比如实体类,工具类等等

服务提供者(C):microservice-student-provider-1001(用于操作数据库并且被浏览器所访问)

服务消费者(C):microservice-student-consumer-80(用于通过restful api来调用服务提供者的接口)

微服务架构注意点:

1、SpringBoot、SpringCloud版本在父工程定义

2、由于通用模块无需操作数据库,但SpringBoot项目启动是默认会读取数据库,所以得在启动类添加以下注解@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

3、分布式jpa需要在启动类上添加@EntityScan("com.ue.entity")跟@EnableJpaRepositories("com.ue.repository")

4、消费者需要添加配置类获取org.springframework.web.client.RestTemplate,因为SpringCloud底层是通过RestTemplate来调用服务提供者提供的服务的

传统项目拆分成微服务架构图如下:

创建父工程(microservice)

父工程是一个maven项目,用一般创建方式即可,父工程的主要用途是锁定pom依赖包版本。由于springcloud2.x停止更新,这里我们采用稳定的低版本,配套的springboot版本为1.x版本

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.ue</groupId>
  <artifactId>microservice</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <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>
    <druid.version>1.1.10</druid.version>
  </properties>

  <!--锁定pom依赖jar包版本,但并不实际引用(即用于继承)-->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.SR4</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>1.5.13.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--连接池-->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>${druid.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

创建通用模块(microservice-common)

通用模块主要存放实体类、工具包等被整个微服务框架所使用的代码,创建一个简单的springboot模块即可,相关代码如下

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.ue</groupId>
        <artifactId>microservice</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>microservice-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

MicroserviceCommonApplication.java:

package com.ue;

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;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class MicroserviceCommonApplication {

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

}

Student.java:

package com.ue.entity;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "t_springcloud_student")
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    @Column(length = 50)
    private String name;

    @Column(length = 50)
    private String grade;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }
}

创建服务提供者(microservice-student-provider-1001)

创建一个简单的springboot模块,这里需要操作数据库并且被浏览器所访问,故需要添加相关代码如下

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.ue</groupId>
        <artifactId>microservice</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>microservice-student-provider-1001</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ue</groupId>
            <artifactId>microservice-common</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

application.yml:

server:
  port: 1001
  context-path: /
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demosite1?useUnicode=true&characterEncoding=utf8
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

MicroserviceStudentProvider1001Application.java:

package com.ue;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EntityScan("com.ue.entity")
@EnableJpaRepositories("com.ue.repository")
public class MicroserviceStudentProvider1001Application {

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

}

StudentRepository.java:

package com.ue.repository;

import com.ue.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface StudentRepository extends JpaRepository<Student, Integer>, JpaSpecificationExecutor<Student> {
 
}

StudentService.java:

package com.ue.service;
 
import com.ue.entity.Student;
import java.util.List;

/**
 * 学生信息Service接口
 * @author Administrator
 */
public interface StudentService {
 
    /**
     * 添加或者修改学生信息
     * @param student
     */
    public void save(Student student);
     
    /**
     * 根据id查找学生信息
     * @param id
     * @return
     */
    public Student findById(Integer id);
     
    /**
     * 查询学生信息
     * @return
     */
    public List<Student> list();
     
    /**
     * 根据id删除学生信息
     * @param id
     */
    public void delete(Integer id);
}

StudentServiceImpl.java:

package com.ue.service.impl;
 
import java.util.List;
import javax.annotation.Resource;
import com.ue.entity.Student;
import com.ue.repository.StudentRepository;
import com.ue.service.StudentService;
import org.springframework.stereotype.Service;

/**
 * 学生信息Service实现类
 * @author Administrator
 */
@Service("studentService")
public class StudentServiceImpl implements StudentService {
 
    @Resource
    private StudentRepository studentRepository;
     
    @Override
    public void save(Student student) {
        studentRepository.save(student);
    }
 
    @Override
    public Student findById(Integer id) {
        return studentRepository.findOne(id);
    }
 
    @Override
    public List<Student> list() {
        return studentRepository.findAll();
    }
 
    @Override
    public void delete(Integer id) {
        studentRepository.delete(id);
    }
 
}

StudentProviderController.java:

package com.ue.controller;
 
import java.util.List;
import javax.annotation.Resource;
import com.ue.entity.Student;
import com.ue.service.StudentService;
import org.springframework.web.bind.annotation.*;

/**
 * 服务提供者-学生信息控制器
 * @author Administrator
 */
@RestController
@RequestMapping("/student")
public class StudentProviderController {
 
    @Resource
    private StudentService studentService;
     
    /**
     * 添加或者修改学生信息
     * @param student
     * @return
     */
    @PostMapping(value="/save")
    public boolean save(Student student){
        try{
            studentService.save(student);  
            return true;
        }catch(Exception e){
            return false;
        }
    }
     
    /**
     * 查询学生信息
     * @return
     */
    @GetMapping(value="/list")
    public List<Student> list(){
        return studentService.list();
    }
     
    /**
     * 根据id查询学生信息
     * @return
     */
    @GetMapping(value="/get/{id}")
    public Student get(@PathVariable("id") Integer id){
        return studentService.findById(id);
    }
     
    /**
     * 根据id删除学生信息
     * @return
     */
    @GetMapping(value="/delete/{id}")
    public boolean delete(@PathVariable("id") Integer id){
        try{
            studentService.delete(id);
            return true;
        }catch(Exception e){
            return false;
        }
    }
}

创建服务消费者(microservice-student-consumer-80)

服务消费者主要是通过restful api来调用服务提供者的接口,故不需要操作数据库,相关配置如下

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.ue</groupId>
        <artifactId>microservice</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>microservice-student-consumer-80</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ue</groupId>
            <artifactId>microservice-common</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

application.yml:

server:
  port: 80
  context-path: /

MicroserviceStudentConsumer80Application.java:

package com.ue;

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;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class MicroserviceStudentConsumer80Application {

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

}

SpringCloudConfig.java:

package com.ue.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * SpringCloud相关配置
 * @author Administrator
 */
@Configuration
public class SpringCloudConfig {

    /**
     * 调用服务模版
     * @return
     */
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

StudentConsumerController.java:

package com.ue.controller;
 
import java.util.List;
import javax.annotation.Resource;

import com.ue.entity.Student;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * 
 * @author Administrator
 *
 */
@RestController
@RequestMapping("/student")
public class StudentConsumerController {
 
     @Resource
     private RestTemplate restTemplate;
      
     /**
      * 添加或者修改学生信息
      * @param student
      * @return
      */
     @PostMapping(value="/save")
     private boolean save(@RequestBody Student student){
         return restTemplate.postForObject("http://localhost:1001/student/save", student, Boolean.class);
     }
      
     /**
     * 查询学生信息
     * @return
     */
    @GetMapping(value="/list")
    public List<Student> list(){
        return restTemplate.getForObject("http://localhost:1001/student/list", List.class);
    }
     
    /**
     * 根据id查询学生信息
     * @return
     */
    @GetMapping(value="/get/{id}")
    public Student get(@PathVariable("id") Integer id){
        return restTemplate.getForObject("http://localhost:1001/student/get/"+id, Student.class);
    }
     
    /**
     * 根据id删除学生信息
     * @return
     */
    @GetMapping(value="/delete/{id}")
    public boolean delete(@PathVariable("id") Integer id){
        try{
            restTemplate.getForObject("http://localhost:1001/student/delete/"+id, Boolean.class);
            return true;
        }catch(Exception e){
            return false;
        }
    }
}

测试时先启动服务提供者再启动服务消费者,部分测试结果如下:

注意:用postman测试新增接口的时候,服务提供端的实体参数前面要加上@RequestBody注解,否则会接收不到数据

附:在idea里配置Run Dashboard来运行分布式项目

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章