SpringColud

*SpringColud*

*一、SpringClouad简介*

*1、微服务概述*

*1.1 什么是微服务*

"微服务”一词源于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到 http://martinfowler.com/articles/microservices.html

  • 微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间一般通过 HTTP 的 RESTfuLAPI 进行通信协作。
  • 被拆分成的每一个小型服务都围绕着系统中的某一项或些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发自动化测试案例以及独立部署机制。
  • 由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。

微服务架构特点:

  • 单一职责
  • 服务粒度小
  • 面向服务(对外暴露REST api)
  • 服务之间相互独立

*2、SpringColud概述*

*2.1 什么是Spring Cloud*

Spring Cloud 是分布式微服务架构的一站式解决方案,它提供了一套简单易用的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务系统的构建。
Spring Cloud 被称为构建分布式微服务系统的“全家桶”,它并不是某一门技术,而是一系列微服务解决方案或框架的有序集合。它将市面上成熟的、经过验证的微服务框架整合起来,并通过 SpringBoot 的思想进行再封装,屏蔽调其中复杂的配置和实现原理,最终为开发人员提供了一套简单易懂、易部署和易维护的分布式系统开发工具包。

Spring Cloud 中包含了 spring-cloud-config、spring-cloud-bus 等近 20 个子项目,提供了服务治理、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列、配置管理等领域的解决方案。

Spring Cloud 本身并不是一个拿来即可用的框架,它是一套微服务规范,共有两代实现。

Spring Cloud Netflix 是 Spring Cloud 的第一代实现,主要由 Eureka、Ribbon、Feign、Hystrix 等组件组成。

Spring Cloud Alibaba 是 Spring Cloud 的第二代实现,主要由 Nacos、Sentinel、Seata 等组件组成。

在这里插入图片描述

*2.2Spring Cloud技术生态*

在这里插入图片描述

*2.3 Spring Cloud 和dubbo区别*

在这里插入图片描述

SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。==

严格来说,这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适。都是一种SOA的实现。

*二、SpringColud环境准备*

首先,我们需要模拟一个服务调用的场景。方便后面学习微服务架构。在本案例中我们将采用最新稳定版本的SpringBoot和SpringColud。
SpringColud Version: *Hoxton.SR9*
Supported Boot Version: *2.3.7.RELEASE*

*2.1 创建父工程*

微服务中需要同时创建多个项目,先创建一个父工程,然后后续的工程都以这个工程为父,实现maven的聚合。这样可以在一个窗口看到所有工程。在实际开发中,每个微服务可独立一个工程。

<?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.studycloud</groupId>
  <artifactId>ClouadEasyBuy</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <parent>

    <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-parent</artifactId>

    <version>2.3.7.RELEASE</version>

    <relativePath/>

  </parent>

  <properties>

    <java.version>1.8</java.version>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <project.reporting.outputEncoding>UTF-

      8</project.reporting.outputEncoding>

    <spring-boot.version>2.3.7.RELEASE</spring-boot.version>

    <spring-cloud.version>Hoxton.SR9</spring-cloud.version>

  </properties>

  <dependencies>

    <!--将来使用远程配置用 都继承吧-->

    <dependency>

      <groupId>org.springframework.cloud</groupId>

      <artifactId>spring-cloud-starter-config</artifactId>

    </dependency>

    <!--actuator

    这是springboot程序的监控系统,可以实现健康检查,info信息等。

​    在使用之前需要引入spring-boot-starter-actuator,并做简单的配置即可--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>

  </dependencies>

  <dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>

  </dependencyManagement>

</project>
*2.2 创建模块common*

1)pom:

<dependencies> 

<dependency> 

<groupId>com.baomidou</groupId> 

<artifactId>mybatis-plus-boot-starter</artifactId> 

<version>3.4.3.4</version> 

</dependency> 

</dependencies> 

2)新建包easy.domain

3)复制粘贴entity实体类

4)父工程maven LifeCircle–install

5)目录结构:

在这里插入图片描述

*2.3.新建EasyProductPart7081(商品服务端)*

1)pom:

<dependencies><dependency><groupId>com.studycloud</groupId><artifactId>Common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3.4</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

  </dependencies>

  <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version><configuration><mainClass>easy.EasyProductApp</mainClass><jvmArguments>-Dfile.encoding=UTF-8</jvmArguments></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins>

</build>

2)application.yml:

spring: 
 datasource: 
   type: com.alibaba.druid.pool.DruidDataSource 
   driver-class-name: com.mysql.cj.jdbc.Driver 
   url: jdbc:mysql://127.0.0.1:3306/easy_productdb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8  
   username: root (填自己数据库的用户名) 
   password: xxxx(填自己数据库的密码) 
 application: 
   name: easybuyproduct
server: 
  port: 7081 
mybatis-plus: 
  #mapper-locations: classpath:/mapper/.xml 
  configuration: 
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 
  type-aliases-package: domain.mapper.productdb

3)目录结构
在这里插入图片描述

4)相关注解的使用

关于:@EnableDiscoveryClient 或 @EnableEurekaClient

在SpringCloud中当你需要使用Eureka注册中心的时候你在配置Eureka的客户端的时候需要在启动类上添加@EnableDiscoveryClient 或 @EnableEurekaClient注解 , SpringCloud Edgware 版本以上可以省略.

@SpringBootApplication

@EnableTransactionManagement

public class EasyProductApp {

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

  }

}

 

@RestController

@RequestMapping("/productservice")

public class ProductController {

  @Autowired

  private ProductServiceImpl productService;

  @GetMapping("/products")

  public List<TProduct> listProducts() {return productService.queryAllProducts();

  }

}
*2.4新建EasyClient9081(商品客户端)*

1)POM:

 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.studycloud</groupId><artifactId>Common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

  </dependencies>

  <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>easy.EasyClientApplication</mainClass><jvmArguments>-Dfile.encoding=UTF-8</jvmArguments></configuration></plugin></plugins>

</build>

2)application.yml:

spring: 

   application: 

   name: easybuyclient 

   thymeleaf: 

​     cache: false 

server: 

   port: 9081 

3)目录结构
在这里插入图片描述

  1. 主程序入口:
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) //不连数据库

public class EasyClientApplication {

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

  }

}

5)config代码:

@Configuration

public class ConfigBean {

  @Bean

  @LoadBalanced  //没有LoadBalanced不能按服务名访问

  public RestTemplate getRestTemplate(){return new RestTemplate();

  }

}

6)controller代码:

@Controller 

public class ProductUiController { 

private static String productUrl = "http://localhost:7081"; 

@Autowired 

private RestTemplate restTemplate;

@GetMapping("/products") 

public String products(Model model){ 

List<TProduct>ret=restTemplate.getForObject(productUrl+"/products",List.class); 

model.addAttribute("products",ret); 

return "productlist"; 

}

存在的问题:

1.在EasyClient中,我们把服务url地址硬编码到了代码中,不方便后期维护

2.EasyClient不清楚服务的状态,服务宕机也不知道

3.EasyProductPart只有1台服务,不具备高可用性

4.即便EasyProductPart形成集群,consumer还需自己实现负载均衡

这时候需用到Eureka

*三、Eureka注册中心*

首先我们来解决第一问题,服务的管理

Eureka 一词来源于古希腊词汇,是“发现了”的意思。在软件领域,Eureka 是 Netflix 公司开发的一款开源的服务注册与发现组件。

Spring Cloud 将 Eureka 与 Netflix 中的其他开源服务组件(例如 Ribbon、Feign 以及 Hystrix 等)一起整合进 Spring Cloud Netflix 模块中,整合后的组件全称为 Spring Cloud Netflix Eureka。

Eureka 是 Spring Cloud Netflix 模块的子模块,它是 Spring Cloud 对 Netflix Eureka 的二次封装,主要负责 Spring Cloud 的服务注册与发现功能。

Spring Cloud 使用 Spring Boot 思想为 Eureka 增加了自动化配置,开发人员只需要引入相关依赖和注解,就能将 Spring Boot 构建的微服务轻松地与 Eureka 进行整合。

*Eureka 两大组件*

Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件:

*Eureka Server*:Eureka 服务注册中心,主要用于提供服务注册功能。当微服务启动时,会将自己的服务注册到 Eureka Server。Eureka Server 维护了一个可用服务列表,存储了所有注册到Eureka Server 的可用服务的信息,这些可用服务可以在 Eureka Server 的管理界面中直观看到。

*Eureka Client*:Eureka 客户端,通常指的是微服务系统中各个微服务,主要用于和 EurekaServer 进行交互。在微服务应用启动后,Eureka Client 会向 Eureka Server 发送心跳(默认周期为 30 秒)。若 Eureka Server 在多个心跳周期内没有接收到某个 Eureka Client 的心跳,EurekaServer 将它从可用服务列表中移除(默认 90 秒)。

注:“心跳”指的是一段定时发送的自定义信息,让对方知道自己“存活”,以确保连接的有效性。大部分 CS 架构的应用程序都采用了心跳机制,服务端和客户端都可以发心跳。通常情况下是客户端向服务器端发送心跳包,服务端用于判断客户端是否在线。

*Eureka 服务注册与发现*

Eureka 实现服务注册与发现的原理,如下图所示。

在这里插入图片描述

上图中共涉及到以下 3 个角色:

*服务注册中心(Register Service)*:它是一个 Eureka Server,用于提供服务注册和发现功能。

*服务提供者(Provider Service)*:它是一个 Eureka Client,用于提供服务。它将自己提供的服务注册到服务注册中心,以供服务消费者发现。

*服务消费者(Consumer Service)*:它是一个 Eureka Client,用于消费服务。它可以从服务注册中心获取服务列表,调用所需的服务。

Eureka 实现服务注册与发现的流程如下:

  1. 搭建一个 Eureka Server 作为服务注册中心;

  2. 服务提供者 Eureka Client 启动时,会把当前服务器的信息以服务(spring.application.name)的方式注册到服务注册中心;

  3. 服务消费者 Eureka Client 启动时,也会向服务注册中心注册;

  4. 服务消费者还会获取一份可用服务列表,该列表中包含了所有注册到服务注册中心的服务信息(包括服务提供者和自身的信息);

  5. 在获得了可用服务列表后,服务消费者通过 HTTP 或消息中间件远程调用服务提供者提供的服务。

服务注册中心(Eureka Server)所扮演的角色十分重要,它是服务提供者和服务消费者之间的桥梁。服务提供者只有将自己的服务注册到服务注册中心才可能被服务消费者调用,而服务消费者也只有通过服务注册中心获取可用服务列表后,才能调用所需的服务。

*3. Eureka集群的使用*

*3.1 搭建eureka-server工程*

接下来创建一个项目 EurakaServer7001,启动一个Eureka Server Application服务注册中心。

*添加依赖*

 <artifactId>EurakaServer7001</artifactId>

 

  <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target>

  </properties>

  <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>

  </dependencies>

  <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version><configuration><mainClass>easy.EueakaServer</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins>

</build>

这里需要进行一些修改:

编辑 C:\Windows\System32\drivers\etc 下的hosts

127.0.0.1 host1.com

127.0.0.1 host2.com

127.0.0.1 host3.com

把本机配成三台服务器(假的),host1.com 等,类似于域名。

*编写配置文件 application.yml:*

spring:

 application:

  name: eueakaserver1

server:

 port: 7001

eureka:

 instance:

   hostname: host1.com #eureka服务端的实例名称

 client:

​    register-with-eureka: false #false表示不向注册中心注册自己。

​    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要 去检索服务

​    service-url:

​     \#defaultZone: http://host1.com:7001/eureka

​     defaultZone: http://host2.com:7002/eureka,http://host3.com:7003/eureka #集群版本时

*编写启动类**:*

@SpringBootApplication

@EnableEurekaServer //开启 Eureka server,接受其他微服务的注册

public class EueakaServer {

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

  }

}
*3.2更改ProductPart7081(商品服务端)注册到EurekaServer*

pom引入依赖 :

<!--引入 Eureka Client 的依赖,将服务注册到 Eureka Server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>

Application.yml需要添加的部分:

eureka:

 client:

  service-url:

​    defaultZone: 

 //这里用的是集群

http://host1.com:7001/eureka,http://host2.com:7002/eureka,http://host3.com:7003/eureka

 instance:

  instance-id: easybuyproduct7081

  prefer-ip-address: true

info:

 app:

   name: easybuyproduct

 company:

   name: this is it

 build:

   artifactId: EasyProductPart7081

   version: 1.0-SNAPSHOT

 \#放开监控端点

management:

 endpoints:

  web:

   exposure:

​    include: "*"
*3.3更改EasyClient(客户端),使用服务名调用*

pom引入依赖:

<!--引入 Eureka Client 的依赖,可以将服务注册到 Eureka Server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>

Application.yml:

 eureka:

 client:

   register-with-eureka: false #可以不用注册到 Eureka Server,我们这个可以,真正项目中都是微服务 都注册,消费者也同时可以是提供者

   fetch-registry: true

   service-url:

​    defaultZone:

  //这里用的是集群

 http://host1.com:7001/eureka,http://host2.com:7002/eureka,http://host3.com:7003/eureka

入口程序:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration .class}) @EnableEurekaClient public class EasyClientApplication {

 public static void main(String[] args) {

 SpringApplication.run(EasyClientApplication.class, args); 

} 

}

*调用方式用服务名*

在这里插入图片描述

controller里需要更改一些地方:

在这里插入图片描述

因为我用的是集群,故还需两台Eureka服务器。

复制EurakaServer7001为EurakaServer7002

需要更改的一些地方:

Pom:

<artifactId>EurakaServer7002</artifactId>

Application.yml:

spring:

 application:

  name: eueakaserver2

server:

 port: 7002

eureka:

 instance:

   hostname: host2.com #eureka服务端的实例名称(填写自己的主机名)

 client:

​    register-with-eureka: false #false表示不向注册中心注册自己。

​    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要 去检索服务

​    service-url:

​     \#defaultZone: http://host1.com:7001/eureka

​     defaultZone: http://host1.com:7001/eureka,http://host3.com:7003/eureka #集群版本时(填写除自己外另外两台主机的域名)

再复制EurakaServer7001为EurakaServer7003:

需要更改的一些地方:

Pom:

<artifactId>EurakaServer7003</artifactId>

Application.yml:

spring:

 application:

  name: eueakaserver3

server:

 port: 7003

eureka:

 instance:

   hostname: host3.com #eureka服务端的实例名称

 client:

​    register-with-eureka: false #false表示不向注册中心注册自己。

​    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要 去检索服务

​    service-url:

​     \#defaultZone: http://host1.com:7001/eureka

​     defaultZone: http://host1.com:7001/eureka,http://host2.com:7002/eureka #集群版本时(填写除自己外另外两台主机的域名)

*父工程POM添加model*

 <modules><module>Common</module><module>EasyProductPart7081</module><module>EasyClient9081</module><module>EurakaServer7001</module><module>EurakaServer7002</module><module>EurakaServer7003</module>

  </modules>

分别依次启动三个EurakaServer :

访问localhost:7001:

在这里插入图片描述

访问localhost7002:

在这里插入图片描述

访问localhost7003:

在这里插入图片描述

很明显可以看出每个EurakaServer都有另外两个备用EurakaServer.这时候我们开启商品服务端EasyProductPart7081,服务端会往EurakaServer里注册服务信息,此时再开启商品客户端EasyClient9081,这时候客户端便能从EurakaServer获取到服务信息,进而消费服务。

客户端展示:

在这里插入图片描述

此时我们将三台EurakaServer依次关掉,查看客户端的情况:

关掉EurakaServer7001时,

在这里插入图片描述

在这里插入图片描述

此时客户端不受影响:

在这里插入图片描述

再关掉EurakaServer7002时:

在这里插入图片描述

在这里插入图片描述

此时客户端依旧不受到影响:

在这里插入图片描述

最后再关掉最后一台EurakaServer7003:

在这里插入图片描述

在这里插入图片描述

客户端还是不受到影响:
在这里插入图片描述

因此!可以得出结论:EurakaServer开启后,此时再开启服务端,服务端会往EurakaServer注册服务信息,之后再开启客户端后,客户端会从EurakaServer获取到服务信息,进而消费服务。客户端只要第一次从EurakaServer获取到了服务信息之后,之后再关掉EurakaServer服务,客户端不会受到影响!只要总的服务端不关掉,客户端就不会受到影响!!!

这里用到了EurakaServer集群,平时练习使用的时候单节点即可!

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一个用于构建分布式系统的开发工具集合。它提供了一些常用的组件和框架,包括服务注册和发现、负载均衡、断路器、分布式配置等等。在使用Spring Cloud时,有一些常见的错误和注意事项需要注意。 首先,关于Spring Boot和Spring Cloud版本对应错误。在使用Spring Cloud时,需要确保Spring Boot和Spring Cloud的版本兼容。不同版本之间可能存在依赖冲突或不兼容的情况,因此需要根据官方文档或者相关文档来选择合适的版本。 另外,Spring Cloud Config是一个用于集中管理和动态获取配置的工具。它支持从Git、SVN或本地文件系统中获取配置文件,并提供了服务器和客户端支持。你可以通过官方使用说明文档了解更多关于Spring Cloud Config的详细信息。 此外,关于选择使用Nacos还是Eureka作为服务注册和发现组件的问题。Nacos是一个功能更强大的服务注册和发现组件,它整合了Spring Cloud Eureka、Spring Cloud Config和Spring Cloud Bus的功能。使用Nacos可以实现配置的中心动态刷新,而不需要为配置中心新增集群或使用消息队列。另一方面,Eureka是Spring Cloud原生全家桶的一部分,相对来说更加稳定一些。选择使用哪个组件需要根据具体的需求和项目特点来决定。 综上所述,Spring Cloud是一个用于构建分布式系统的开发工具集合,它提供了一些常用的组件和框架。在使用Spring Cloud时,需要注意Spring Boot和Spring Cloud版本的兼容性,并可以使用Spring Cloud Config来动态获取配置。同时,可以选择使用Nacos或Eureka作为服务注册和发现组件,具体选择需要根据项目需求来决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值