SpringBoot整合SpringCloud的过程详解

目录
  • 1. SpringCloud特点
  • 2. 分布式系统的三个指标CAP
  • 3. Eureka
  • 4. SpringCloud Demo
    • 4.1 registry
    • 4.2 api
    • 4.3 provider
    • 4.4 consumer
    • 4.5 POSTMAN一下

1. SpringCloud特点

SpringCloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况:

  • 分布式/版本化配置
  • 服务注册和发现 Eureka
  • 路由 Zuul
  • 服务到服务的呼叫
  • 负载均衡 Ribbon
  • 断路器 Hystrix
  • 分布式消息传递

2. 分布式系统的三个指标CAP

在介绍SpringCloud默认使用的注册中心前,先介绍分布式系统的三个指标,分别是:

  • Consistency:一致性,在分布式系统中,更新操作执行成功后所有的用户的读操作必须返回最新值;client写入,server同步至整个系统;
  • Availability:可用性,只要收到用户的请求,在一定的时间内服务器就必须给出回应,回应的结果可以是成功或是失败;
  • Partition tolerance:分区容错,即区间通信可能失败,在网络中断,消息丢失的情况下,仍对外提供服务;一般无法避免,可以认为CAP中的P总是成立

CAP定律说的是,在一个分布式计算机系统中,一致性C,可用性A,分区容错性P这三种保证无法同时得到满足,最多满足两个:

1.放弃P

为了避免分区容错性问题的发生,一种做法是将所有与事务相关的数据都放在一台服务器上,虽然不能保证100%系统不会出错,但是不会碰到由分区带来的负面效果,这样的做法会严重影响系统的扩展性。

2.放弃A

放弃可用性,一旦遇到分区容错故障,受到影响的服务器需要等待一定的时间,因此会导致在等待期间系统无法对外提供服务。

3.放弃C

这儿说的放弃一致性,并不是完全放弃数据的一致性,而是放弃数据的强一致性,而保留数据的最终一致性。以网络购物为例,对只剩下一件库存的商品,如果同时接受到了两份订单,那么较晚的订单将被告知商品告罄。

文中部分CAP理论摘自:https://www.cnblogs.com/hxsyl/p/4381980.html

3. Eureka

基本介绍

Eureka是SpringCloud官方推荐用于服务注册和发现,一个基于REST的服务

SpringBoot实现了Netflix OSS的集成,使用Eureka的原因之一是因为其可以利用Spring Cloud Netflix的其他组件:智能路由(Zuul)、客户端负载均衡(Ribbon)等

基本组成

Eureka由多个Instance(服务实例)组成,分为Eureka Server和Eureka Client

其中Eureka Client又可细分为:Service Provider、Service Consumer

  • Eureka Server:服务端,提供服务的注册和发现;
  • Eureka Client:客户端

Service Provider:服务提供方,将自身服务注册到Eureka,让消费方找到Service Consumer:服务消费方,从Eureka获取注册服务列表,从而消费服务

Eureka和Zookeeper

1)由CAP理论的角度来看

Zookeeper:ZK保证CP,突出强一致性,但无法保证每次访问服务可用性,比如ZK会出现这样一种情况:当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举,在ZK选举leader期间整个ZK集群都是不可用的,这就导致了在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得ZK集群失去master节点是较大概率会发生的事儿,虽然服务最终会恢复,但是漫长的选举时间导致的注册长期不可用是难以容忍的。

Eureka:Eureka保证AP,Eureka在设计时就优先保证可用性。对于Eureka中的节点,每个节点都是平等的,几个节点挂掉也不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。但Eureka不保证强一致性,即查到的信息可能不是最新的。此外Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就会认为客户端和注册中心出现了网络故障,但会保证当前节点依然可用,不会像ZK导致整个注册服务瘫痪。

2)由节点分工的角度来看

Zookeeper:ZK集群中节点分为三类,承担不同的任务

  • Leader:事务请求唯一的调度者和处理者(除了查询请求)
  • Follower:处理非事务请求,参与Leader选举投票
  • Observer:处理非事务请求,但不参与Leader选举投票

Eureka:在Eureka集群中每个节点都是平等的,每个节点扮演相同的角色,它们通过相互注册的方式来感知对方的存在,当由注册消息时,它们会同步给集群内的其他节点

中文文档:https://www.springcloud.cc/spring-cloud-greenwich.html

4. SpringCloud Demo

Demo整体结构(父子项目)

  • api:Bean、DTO、POJO等以及Service接口
  • controller:服务消费方,前端交互
  • provider:服务提供方,服务实现
  • registry:服务注册中心

4.1 registry

1)pom.xml

关键点在于导入eureka服务端依赖以及SpringCloud依赖

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-server -->
        <!-- eureka服务端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2)application.properties

进行Eureka服务端的相关配置

spring.application.name=SpringCloudDemoRegistry

# server端口,自己喜欢
server.port=8888

# Eureka Server服务url以及默认zone,结尾必须eureka
eureka.client.service-url.defaultZone= http://127.0.0.1:8888/eureka/

# eureka的自我保护机制,k8s环境下建议false
eureka.server.enable-self-preservation=false

# false表示自己端就是注册中心,我的功能就是维护服务实例,不需要从server获取注册的服务信息
eureka.client.fetch-registry=false

# false表示不将自己注册到Eureka Server
eureka.client.register-with-eureka=false

3)EurekaregistryApplication

使用@EnableEurekaServer激活相关配置,使registry模块作为注册中心Server

@EnableEurekaServer //声明为注册中心服务端
@SpringBootApplication
public class EurekaregistryApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaregistryApplication.class, args);
    }
}

4.2 api

1)entity

实体类以部门和用户信息为例,由于演示使用了Lombok省点代码,用于实现基本的CRUD

Department.class

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Department {
    private Long id;
    private Integer dId;
    private String dName;
    private Date updateTime;
}

UserInfo.class

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
    private Long id;
    private Integer uId;
    private Integer dId;
    private String uName;
    private String uPhone;
    @Email(message = "非法邮件格式") //Validator格式校验
    private String uEmail;
    private String uAddress;
    private Date updateTime;
    private Department department;
}

2)UserService

UserService为服务接口,声明需要提供和消费的方法,写了几个简单查询

public interface UserService {

    /**
     * 判断用户是否存在,0为不存在,返回值与uId相等则存在
     * @param uId
     * @return
     */
    Integer userExist(Integer uId);

    /**
     * 获取用户个人基本信息
     * @param uId
     * @return
     */
    UserInfo getUserInfo(Integer uId);

    /**
     * 获取用户个人详情信息
     * @param uId
     * @return
     */
    UserInfo getUserDetailsInfo(Integer uId);
}

4.3 provider

1)pom.xml

关键点是引入eureka客户端依赖、openfeign依赖、SpringCloud依赖

<dependencies>
    	<!-- Springboot的依赖省略... -->
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
</dependencies>

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

2)application.properties

配置Eureka、Mybatis以及DataSource数据源等信息

spring.application.name=SpringCloudDemoProvider

# Server端口
server.port=9999

# Eureka服务url
eureka.client.service-url.defaultZone= http://127.0.0.1:8888/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true

# Mybatis
mybatis.mapper-locations= classpath:com.maziyao.provider.mapper/*.xml
mybatis.type-aliases-package= com.maziyao.common.entity

# DataSource数据源配置
spring.datasource.type=com.zaxxer.hikari.HikariDataSource

# DataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/boot-demo?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

3)EurekaproviderApplication

provider启动类使用@EnableEurekaClient声明为EurekaClient客户端,作为ServiceProvider

@EnableEurekaClient
@SpringBootApplication
@EnableAspectJAutoProxy
@MapperScan("com.maziyao.provider.mapper")
@ComponentScan(basePackages = {
        "com.maziyao.provider.rest",
        "com.maziyao.provider.redis",
        "com.maziyao.provider.service",
        "com.maziyao.provider.config"
})
public class EurekaproviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaproviderApplication.class, args);
    }
}

4)service

UserServiceImpl作为UserService接口实现类,@Service用于标注业务层组件

自动注入mapper层的mapper接口并调用,mapper的SQL语句下面就略了,很简单

需要注意的是,对于数据访问层组件mapper,使用@Repository进行标注

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public Integer userExist(Integer uId) {
        return userMapper.userExist(uId);
    }

    @Override
    public UserInfo getUserInfo(Integer uId) {
        return userMapper.getUserInfo(uId);
    }

    @Override
    public UserInfo getUserDetailsInfo(Integer uId) {
        return userMapper.getUserDetailsInfo(uId);
    }
}

5)rest

重点是rest包下的UserServer,要知道Eureka是一个基于REST的服务

使用@RestController标注并声明为userServer,这个是SpringBoot注解,用于标注控制层组件

@RestController("userServer")
public class UserServer {

    public static final Logger logger = LoggerFactory.getLogger(UserServer.class);

    @Autowired
    private UserService userService;

    @ResponseBody
    @RequestMapping(value = "/exist",method = RequestMethod.GET)
    public Integer existUserByUid(@RequestParam("uId")Integer uId){
        return userService.userExist(uId);
    }

    @ResponseBody
    @RequestMapping(value = "/userInfo",method = RequestMethod.GET)
    public UserInfo getUserInfo(@RequestParam("uId")Integer uId){
        return userService.getUserInfo(uId);
    }

    @ResponseBody
    @RequestMapping(value="/userDetailsInfo",method = RequestMethod.GET)
    public UserInfo getUserDetailsInfo(@RequestParam("uId")Integer uId){
        return userService.getUserDetailsInfo(uId);
    }
}

4.4 consumer

1)pom.xml

在Controller的pom.xml中也需要导入EurekaClient的依赖,对于Provider和Controller都为Client

<dependencies>
    	<!-- SpringBoot依赖省略... -->
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
</dependencies>

2)application.properties

在application.properties中配置Eureka相关信息

spring.application.name=springCloudDemoController

# Server端口
server.port=8899

# 注册中心url
eureka.client.service-url.defaultZone= http://127.0.0.1:8888/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true

3)EurekacontrollerApplication

与Provider的启动类一致,声明启动类为Eureka的客户端

并使用@EnableFeignClients开启Feign,声明性的web服务客户端

@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
@EnableAspectJAutoProxy
@ComponentScan({
        "com.maziyao.controller.config",
        "com.maziyao.controller.controller",
        "com.maziyao.controller.rest"
})
public class EurekacontrollerApplication {

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

}

4)rest

controller作为前端交互层,即控制层,此处UserClient声明调用方法

使用@FeignClient声明服务提供方在application.properties中配置的spring.application.name

以及绑定服务提供方对应rest包下的UserServer类的@RestController("userServer")

@FeignClient(name = "springCloudDemoProvider",contextId = "userServer")
public interface UserClient {

    @ResponseBody
    @RequestMapping(value = "/exist",method = RequestMethod.GET)
    public Integer existUserByUid(@RequestParam("uId")Integer uId);

    @ResponseBody
    @RequestMapping(value = "/userInfo",method = RequestMethod.GET)
    public UserInfo getUserInfo(@RequestParam("uId")Integer uId);

    @ResponseBody
    @RequestMapping(value="/userDetailsInfo",method = RequestMethod.GET)
    public UserInfo getUserDetailsInfo(@RequestParam("uId")Integer uId);

}

5)UserController

控制层,使用@RestController标注,并注入UserClient进行调用

@RestController
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserClient userClient;

    @ResponseBody
    @RequestMapping(value = "/exist",method = RequestMethod.GET)
    public Integer existUserByUid(@RequestParam("uId") Integer uId){
        return userClient.existUserByUid(uId);
    }

    @ResponseBody
    @RequestMapping(value = "/userInfo",method = RequestMethod.GET)
    public UserInfo getUserInfoByUid(@RequestParam("uId")Integer uId){
        return userClient.getUserInfo(uId);
    }

    @ResponseBody
    @RequestMapping(value = "/userDetailsInfo",method = RequestMethod.GET)
    public UserInfo getUserDetailsInfoByUid(@RequestParam("uId")Integer uId){
        return userClient.getUserDetailsInfo(uId);
    }

}

4.5 POSTMAN一下

注意:最后记得mvn install,需要先将registry运行起来,再分别运行provider和controller

启动registry:

启动provider:

启动consumer:

result:

到此这篇关于SpringBoot整合SpringCloud的文章就介绍到这了,更多相关SpringBoot整合SpringCloud内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程详解

    注意:适用于springboot或者springcloud框架 1.首先下载相关文件 2.然后需要去启动相关的启动文件 3.导入相关jar包(如果有相关的依赖包不需要导入)以及配置配置文件,并且写一个dao接口继承一个类,在启动类上标注地址 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> &l

  • 从零开始搭建springboot+springcloud+mybatis本地项目全过程(图解)

    记录一下从零开始搭建一个springboot+springcloud+mybatis本地项目的demo的过程.纯代码小白一枚,若有不足或错误之处,欢迎广大朋友指出! 开发环境准备: IDE:IntelliJ Idea 2019.3 数据库:mysql 8.0.2.2 SpringBoot版本:2.2.0.RELEASE SpringCloud版本:Hoxton.RELEASE 一.创建一个新的Idea项目 打开Idea,单击New->File->Project,选择Maven,直接下一步 输入

  • springboot集成springCloud中gateway时启动报错的解决

    在项目中引入springcloud中的gateway时报以下错误 Description: Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigur

  • SpringBoot+SpringCloud用户信息微服务传递实现解析

    这篇文章主要介绍了SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 实现思路: 1:准备一个ThreadLocal变量,供线程之间共享. 2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中. 3:每个微服务在使用FeignClient调用别的微服务时,先从ThreadLocal里面取出user信息,并

  • SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解决方案

    hystrix参数使用方法 通过注解@HystrixCommand的commandProperties去配置, 如下就是hystrix命令超时时间命令执行超时时间,为1000ms和执行是不启用超时 @RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("/movie/{id}") @HystrixCommand(commandPro

  • 详解SpringBoot与SpringCloud的版本对应详细版

    缘起 初学spring cloud的朋友可能不知道,其实SpringBoot与SpringCloud需要版本对应,否则可能会造成很多意料之外的错误,比如eureka注册了结果找不到服务类啊,比如某些jar导入不进来啊,等等这些错误.下面列出来springBoot和spring cloud的版本对应关系,需要配套使用,才不会出现各种奇怪的错误. 关于maven仓库的版本列表 spring-cloud-dependencies 版本列表可查看: https://mvnrepository.com/a

  • SpringBoot整合SpringCloud的过程详解

    目录 1. SpringCloud特点 2. 分布式系统的三个指标CAP 3. Eureka 4. SpringCloud Demo 4.1 registry 4.2 api 4.3 provider 4.4 consumer 4.5 POSTMAN一下 1. SpringCloud特点 SpringCloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况: 分布式/版本化配置 服务注册和发现 Eureka 路由 Zuul 服务到服务的呼叫 负载均衡 Ribbon 断路器 H

  • SpringBoot整合Druid数据源过程详解

    这篇文章主要介绍了SpringBoot整合Druid数据源过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.数据库结构 2.项目结构 3.pom.xml文件 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</ar

  • springboot整合shiro的过程详解

    目录 什么是 Shiro Shiro 架构 Shiro 架构图 Shiro 工作原理 Shiro 详细架构图 springboot 整合 shiro springboot 整合 shiro 思路 项目搭建 主要依赖 数据库表设计 实体类 自定义 Realm shiro 的配置类 ShiroFilterFactoryBean 过滤器链配置中的 url 匹配规则 ShiroFilterFactoryBean 过滤器 ShiroFilterFactoryBean 过滤器分类 前端页面 登录页面 log

  • SpringBoot整合FastDFS方法过程详解

    一.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

  • SpringBoot整合Swagger2的步骤详解

    简介 swagger是一个流行的API开发框架,这个框架以"开放API声明"(OpenAPI Specification,OAS)为基础, 对整个API的开发周期都提供了相应的解决方案,是一个非常庞大的项目(包括设计.编码和测试,几乎支持所有语言). springfox大致原理: springfox的大致原理就是,在项目启动的过种中,spring上下文在初始化的过程, 框架自动跟据配置加载一些swagger相关的bean到当前的上下文中,并自动扫描系统中可能需要生成api文档那些类,

  • SpringBoot整合rockerMQ消息队列详解

    目录 Springboot整合RockerMQ 使用总结 消费模式 生产者组和消费者组 生产者投递消息的三种方式 如何保证消息不丢失 顺序消息 分布式事务 Springboot整合RockerMQ 1.maven依赖 <dependencies> <!-- springboot-web组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>

  • SpringBoot开发存储服务器实现过程详解

    目录 正文 基础环境 创建项目 添加Rest API接口功能(提供上传服务) 启动服务,测试API接口可用性 增加下载文件支持 文件大小设置 打包文件部署 正文 今天我们尝试Spring Boot整合Angular,并决定建立一个非常简单的Spring Boot微服务,使用Angular作为前端渲编程语言进行前端页面渲染. 基础环境 技术 版本 Java 1.8+ SpringBoot 1.5.x 创建项目 初始化项目 mvn archetype:generate -DgroupId=com.e

  • SpringBoot整合Shiro的代码详解

    shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/  它提供了很方便的权限认证和登录的功能. 而springboot作为一个开源框架,必然提供了和shiro整合的功能!接下来就用springboot结合springmvc,mybatis,整合shiro完成对于用户登录的判定和权限的验证. 1.准备数据库表结构 这里主要涉及到五张表:用户表,角色表(用户所拥有的角色),权限表(角色所涉及到的权限),用户-角色表(用户和角色是多对多的),角色-权限表

  • spring整合Quartz框架过程详解

    这篇文章主要介绍了spring整合Quartz框架过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.Quartz框架简介 Quartz是一个完全由Java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间.其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性.主要用来执行定时任务,如:定时发送信息.定时生成报表等等. Quartz框架的主要特点: · 强大的调度功能,例如丰富多样的

  • SpringBoot整合MongoDB的步骤详解

    项目结构: 1.pom引入mongodb依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 2 配置application.properties #spring.data.mongodb.host=127.0.0.1 #spr

随机推荐