1 springcloud入门概述

1.1 什么是springcloud

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_ci

  • springcloud,基于springboot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件;
    除了基于Netflix的开源组件做高度抽象封装之外,还有一些选型中立的开源组件。
  • sprincloud利用springboot的开发便利性,巧妙地简化了分布式系统基础设施的开发,springcloud为开发人员提供了快速构建分布式的一些列工具,
    包括配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,决策竞选,分布式会话等等,他们都可以用springboot的开发风格做到一键启动和部署
  • springcloud并没有重复造轮子,它只是将目前各家公司开发比较成熟,经得起实际考验的服务架构组合起来,通过springcloud风格进行封装,屏蔽掉了复杂的配置和实现原理,
    最终给开发者留出了一套简单易懂,易部署和易维护的分布式系统开发工具包
  • springcloud是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶

1.2 spingboot与springcloud的关系

  • springboot专注于快速方便的开发单个个体微服务
  • springcloud是关注全局服务协调整体治理框架,它将springboot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供配置管理,服务发现,断路器,路由,事件总线,全局锁,决策竞选,分布式会话等等
  • springboot可以离开springcloud单独使用,开发项目,但是springcloud离不开springboot,属于依赖关系
  • springboot专注于快速方便的开发单个个体微服务,springcloud是关注全局服务协调整体治理框架

1.3 Dubbo和springcloud技术选型

互联网架构图

目前成熟互联网架构图:应用服务化拆分+消息中间件

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_微服务_02

Dubbo和springcloud对比

可以看一下社区活跃度
https://github.com/dubbo https://github.com/springcloud

Dubbo

springcloud

服务注册中心

zookeeper

springcloud netfix Eureka

服务调用方式

RPC

Rest API

服务监控

Dubbo-monitor

springboot admin

断路器

不完善

springcloud netfix Hystrix

服务网关


springcloud netfix zuul

分布式配置


springcloud netfix config

服务跟踪


springcloud netfix sleuth

消息总线


springcloud netfix bus

数据流


springcloud netfix stream

批量任务


springcloud netfix task

最大区别:springcloud抛弃了dubbo的RPC通信,采用的是基于http的rest方式
严格来说,这两种方式各有优劣,虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到原生RPC带来的问题。
而rest比rpc更为灵活,服务提供和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这种强调快速演化下的微服务环境下,显得更合适
品牌机与组装机的区别
很明显 springcloud的功能比dubbo更强大,涵盖面更广,而且作为spring的拳头项目,它也能够与springFramework springboot springdata spring batch 等其他spring项目完美融合,
这些对于微服务而言至关重要。使用dubbo构建的微服务就像组装电脑,各个环节高度自由,但是最终可能某一个小问题导致开启失败,总让人不怎么放心,如果你是一名高手,那么这问题都不是存在;
而springcloud就像品牌机,在spring source的整合下,做了大量的兼容性测试,保证了机器拥有更高稳定性,但是如果要在非原装组件外的东西,就需要对其基础有足够的了解。
社区支持与更新力度
重要的是dubbo停止了5年左右的更新,在2017.7重启了,对于技术发展的新需求,需要有开发者自行拓展升级,这对很多采用微服务的中小软件组织不太合适,中小公司没有那么强大的技术去修改dubbo源码+周边一套解决方案。
总结
解决的问题域不一样:Dubbo的定位是一款RPC框架,springcloud的目标是微服务架构下的一站式解决方案

1.4 springcloud能干嘛

  • Distributed/versioned configuration 分布式/版本控制配置
  • Service registration and discovery 服务注册与发现
  • Routing 路由
  • Service-to-service calls 服务到服务的调用
  • Load balancing 负载均衡配置
  • Circuit Breakers 断路器
  • Distributed messaging 分布式消息管理

1.5 springcloud下载

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_java_03

springcloud 没有采用数字编号的方式命名版本号,而是采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序
自学参考书

2 springcloud rest学习环境搭建:服务提供者

2.1 项目结构介绍

  • 使用一个Dept部门模块做一个微服务通用案例Consumer消费者(Client)通过REST调用Provider提供者(Server)提供的服务。
  • Maven的分分模块架构
一个简单的maven模块结构:
-- app-parent:一个父项目(app-parent)聚合了很多子项目(app-util\app-dao\app-web)
	| --pom.xml
	|
	| --app-core
	|| ----pom.xml
	|
	| --app-web
	|| ----pom.xml
	....

一个父工程带着多个Moudule子模块
SpringCloudDemo父工程(Project)下带着3个子模块(Module)

springcloud-api 【封装的整体entity/接口/公共配置等】
springcloud-consumer-dept-80 【服务提供者】
springcloud-provider-dept-8001 【服务消费者】

2.2 springcloud版本选择

重要版本说明

springboot

springcloud

关系

1.2.x

Angel版本(天使)

兼容springboot1.2.x

1.3.x

Brixton版本(布里克斯顿)

兼容SpringBoot1.3.x,也兼容SpringBoot1.4.x

1.4.x

Camden版本(卡姆登)

兼容SpringBoot1.4.x,也兼容SpringBoot1.5.x

1.5.x

Dalston版本(多尔斯顿)

兼容SpringBoot1.5.x,不兼容SpringBoot2.0.x

1.5.x

Edgware版本(埃奇韦尔)

兼容SpringBoot1.5.x,不兼容SpringBoot2.0.x

2.0.x

Finchley版本(芬奇利)

兼容SpringBoot2.0.x,不兼容SpringBoot1.5.x

2.1.x

Greenwich版本(格林威治)

实际开发版本关系

spring-boot-start-parent

发布日期

spring-cloud-dependencles

发布日期

1.5.2.RELEASE

2017-03

Dalston.RC1

2017-x

1.5.9.RELEASE

2017-11

Edgware.RELEASE

2017-11

1.5.16.RELEASE

2018-04

Edgware.SR5

2018-10

1.5.20.RELEASE

2018-09

Edgware.SR5

2018-10

2.0.2.RELEASE

2018-05

Fomchiey.BULD-SNAPSHOT

2018-x

2.0.6.RELEASE

2018-10

Fomchiey-SR2

2018-10

2.1.4.RELEASE

2019-04

Greenwich.SR1

2019-03

2.3 父工程

创建一个demoparent模块,再在里面创建api、生产者及消费者模块(选中部分为eureka注册中心,暂时可以不需要,后面会介绍

项目大致结构如下

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_spring_04


创建一个对应的数据库

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_spring_05

父工程的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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>springcloud</groupId>
    <artifactId>demo-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>api</module>
        <module>provider-dept-8001</module>
        <module>consumer-dept-8080</module>
        <module>eureka-8000</module>
    </modules>

    <!--定义版本号-->
    <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>
        <lombok.version>1.18.16</lombok.version>
        <log4j.version>1.2.17</log4j.version>
        <logback-core.version>1.2.3</logback-core.version>
        <mysql-connector-java.version>8.0.21</mysql-connector-java.version>
        <druid.version>1.1.23</druid.version>
        <mybatis-spring-boot-starter.version>2.1.4</mybatis-spring-boot-starter.version>
        <spring-boot-dependencies.version>2.3.8.RELEASE</spring-boot-dependencies.version>
        <spring-cloud-dependencies.version>Hoxton.SR9</spring-cloud-dependencies.version>
    </properties>

    <!--这只是依赖管理,如果子项目需要用到依赖,只是省略了版本号而已,实际上还是要导依赖-->
    <dependencyManagement>
        <dependencies>
            <!--很重要的包:springcloud的依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springboot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--数据库-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-java.version}</version>
            </dependency>
            <!--数据源-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!--mybatis的springboot启动器-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot-starter.version}</version>
            </dependency>
            <!--日志测试-->
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
            <!--log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>${logback-core.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <!--打包插件-->
    </build>

</project>

2.4 API工程

api将实体拆分为一个单独工程,方便后期在其他工程中添加依赖使用

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>demo-parent</artifactId>
        <groupId>springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

实体bean

@Data
@Accessors(chain = true)
@NoArgsConstructor
public class Dept implements Serializable {

    private static final long serialVersionUID = -1L;

    private int id;

    private String deptName;

    private String deptSource;

}

2.5 提供者

yml

server:
  port: 8001

mybatis:
  mapper-locations: classspath*:mapper/*.xml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true&allowMultiQueries=true
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource

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>demo-parent</artifactId>
        <groupId>springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>provider-dept-8001</artifactId>

    <dependencies>
        <!--我们需要拿到实体类,所以要配置api module-->
        <dependency>
            <groupId>springcloud</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!--日志门面-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--jetty:尝试着用这个当应用服务器,与Tomcat没什么区别-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <!--热部署工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

</project>

mapper

@Mapper
@Repository
public interface DeptMapper {

    @Select("select id,dept_name deptName, dept_source  deptSource from dept")
    List<Dept> findAllDept();

    @Select("select id,dept_name deptName, dept_source  deptSource from dept where id = #{id}")
    Dept findById(int id);

    @Insert("insert into dept(dept_name) values (#{deptName})")
    int addDept(Dept dept);

}

service

接口

public interface DeptService {

    List<Dept> findAllDept();

    Dept findById(int id);

    int addDept(Dept dept);
}

实现类

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    DeptMapper deptMapper;

    @Override
    public List<Dept> findAllDept() {
        return deptMapper.findAllDept();
    }

    @Override
    public Dept findById(int id) {
        return deptMapper.findById(id);
    }

    @Override
    public int addDept(Dept dept) {
        return deptMapper.addDept(dept);
    }
}

controller

@RestController
@RequestMapping(value = "/dept")
public class DeptController {
    @Autowired
    DeptService deptService;

    @GetMapping("/findAllDept")
    public List<Dept> findAllDept() {
        return deptService.findAllDept();
    }

    @GetMapping("/findById/{id}")
    public Dept findById(@PathVariable("id") int id) {
        return deptService.findById(id);
    }

    @PostMapping("/addDept")
    public int addDept(@RequestBody Dept dept) {
        return deptService.addDept(dept);
    }
}

启动类

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

测试信息

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_ci_06

3 springcloud rest学习环境搭建:消费者

3.1 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>demo-parent</artifactId>
        <groupId>springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer-dept-8080</artifactId>
    
    <dependencies>
        <dependency>
            <artifactId>demo-parent</artifactId>
            <groupId>springcloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>springcloud</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--热部署工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

    </dependencies>

</project>

3.2 yml

server:
  port: 8080

3.3 RestTemplateConfig

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

3.4 controller

@RestController
@RequestMapping("/dept")
public class DeptController {
    @Autowired
    private RestTemplate restTemplate;

    private static final String REST_URL_PREFIX = "http://localhost:8001/dept/";

    @GetMapping("/findAll")
    public List<Dept> findAll() {
        return restTemplate.getForObject(REST_URL_PREFIX + "findAllDept", List.class);
    }

    @GetMapping("/findById/{id}")
    public Dept findById(@PathVariable("id") int id) {
        return restTemplate.getForObject(REST_URL_PREFIX + "findById/" + id, Dept.class);
    }

    @PostMapping("/addDept")
    public int addDept(@RequestBody Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX + "addDept", dept, Integer.class);
    }
}

3.5 启动类

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

3.6 测试信息

spring kakfa获取消费者有多少个分区 springcloud提供者与消费者_java_07