Spring Cloud

什么是Spring Cloud?

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.

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

大白话是,Spring Cloud是微服务的大管家

Spring Cloud五大重要组件:

  • 服务发现——Netflflix Eureka

  • 客服端负载均衡——Netflflix Ribbon/Feign

  • 服务网关——Netflflix Zuul

  • 断路器——Netflflix Hystrix

  • 分布式配置——Spring Cloud Confifig

什么是微服务?

这里先引用wiki上的一段定义:

微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。

为什么需要微服务?

传统的单体应用,它有着悠久的历史,从Web应用发展的早期一直到今天有着非常多的应用。单体架构无疑是一个成功的架构设计,当你只想做一个小的应用或者Web服务时,它是一个最优的选择,但互联网发展到今天,互联网的体量已经是早期的成千上万倍,用单体架构去服务上千万甚至上亿的用户显然是极度困难的。

单体架构在现阶段遇到的问题:

  1. 难以横向扩展(伸缩性差),无法根据需要单独提升系统中某一模块的性能。
  2. 系统内部错综复杂难以维护。
  3. 交付效率低,必须以大版本的形式统一交付。
  4. 可靠性差,一小块代码的错误可能导致整个系统宕机。
  5. 无法升级现有技术,系统中牵一发而动全身。
    当然单体应用也是有它对应的优点,比如易于开发、易于测试、易于部署,但是它的缺点更加的显而易见和不可协调。

微服务架构相对单体架构的优势:

  1. 可维护性高,每个小组或者开发只需要深入理解自己所负责的模块。
  2. 易于部署,每个服务可以单独进行发布,不会影响整体服务。
  3. 易于横向扩展,可以根据需要单独提升系统中某一模块的性能。
  4. 交付速度快,可维护性高和易于部署解决了交付困难的问题。
  5. 技术升级简单,每个模块可以单独升级框架或语言,互不影响。
  6. 可靠性高,单个服务出现问题不会导致整体系统宕机。
    以上的优势都是在现代软件开发过程中必不可少的需求,应对互联网现在越来越快的发展速度,小步快跑(减少每次迭代功能、增加迭代次数、减少试错成本)必然成为未来的发展方向,所以采用微服务重构单体架构势在必行。

为什么需要Spring Cloud?

大白话,需要Spring Cloud来管理这些微服务啊。

什么是Dubbo

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)。其核心部分是远程通讯,集群容错和自动发现等。

首先,我们来看Spring Cloud和dubbo都支持哪些功能。

image-20200327002410735

注册中心Eureka

创建EurekaServer

先创建一个maven的聚合工程,在父工程中配置springcloud的相关信息,然后再添加一个模块,在模块中创建EurekaServer。

  1. 创建聚合工程聚合工程中主要是配置springcloud的版本信息,以及依赖。

    <?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.lucas</groupId>
        <artifactId>springcloud-lucas</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
    
        <modules>
            <!--要依赖的模块-->
            <module>cloud-eureka</module>
        </modules>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.4.RELEASE</version>
            <relativePath/>
        </parent>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
        </properties>
    
        <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>
            </dependencies>
        </dependencyManagement>
    
    </project>
    
  2. 创建EurekaServer

    <?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>springcloud-lucas</artifactId>
            <groupId>com.lucas</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-eureka</artifactId>
    
    <!--    添加依赖-->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    
  3. 创建启动类

    package com.lucas.eureka;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication.class, args);
        }
    }
    
  4. 创建配置文件

    image-20200327012936851

    #应用程序名称
    spring:
      application:
        name: cloud-eureka
    #服务端口号
    server:
      port: 8000
    eureka:
      client:
        #是否注册到Eureka,如果是单机版不需要注册到其他Eureka
        register-with-eureka: false
        #表示是否从Eureka Server获取注册信息,默认为true。
        fetch-registry: false
        service-url:
          #对外提供服务的url
          defaultZone: http://127.0.0.1:${server.port}/eureka/
    
  5. 测试

    启动main方法eureka就启动成功了。

    image-20200327013106961

Eureka集群

注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中

心是最重要的基础部分,理应随时处于可以提供服务的状态。为了维持其可用性,使用集群是很好的解

决方案。Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他

可用的serviceUrl就能实现高可用部署。

在生产中我们可能需要三台或者大于三台的注册中心来保证服务的稳定性,配置的原理就是将注册中心

分别指向其它的注册中心。每台注册中心分别又指向其它两个节点即可,使用application.yml来配置。

application-8001.yml

#应用程序名称
spring:
  application:
    name: cloud-eureka
#服务端口号
server:
  port: 8001
eureka:
  instance:
    hostname: eureka8001
  client:
    #是否注册到Eureka,如果是单机版不需要注册到其他Eureka
    register-with-eureka: true
    #表示是否从Eureka Server获取注册信息,默认为true。
    fetch-registry: true
    service-url:
      #对外提供服务的url
    defaultZone: http://eureka8002:8002/eureka/,http://eureka8003:8003/eureka/

application-8002.yml

#应用程序名称
spring:
  application:
    name: cloud-eureka
#服务端口号
server:
  port: 8002
eureka:
  instance:
    hostname: eureka8002
  client:
    #是否注册到Eureka,如果是单机版不需要注册到其他Eureka
    register-with-eureka: true
    #表示是否从Eureka Server获取注册信息,默认为true。
    fetch-registry: true
    service-url:
      #对外提供服务的url
    defaultZone: http://eureka8001:8001/eureka/,http://eureka8003:8003/eureka/

application-8003.yml

#应用程序名称
spring:
  application:
    name: cloud-eureka
#服务端口号
server:
  port: 8003
eureka:
  instance:
    hostname: eureka8003
  client:
    #是否注册到Eureka,如果是单机版不需要注册到其他Eureka
    register-with-eureka: true
    #表示是否从Eureka Server获取注册信息,默认为true。
    fetch-registry: true
    service-url:
      #对外提供服务的url
    defaultZone: http://eureka8001:8001/eureka/,http://eureka8002:8002/eureka/

以上的配置中配置了 hostname 属性,需要在hosts文件中配置host名称和ip的映射关系:

修改本机的host文件。

# Eureka 
127.0.0.1 eureka8001 
127.0.0.1 eureka8002 
127.0.0.1 eureka8003

创建三个配置文件,在启动参数中配置使用的配置文件名称,启动三个实例就可以:

// EurekaApplication-8001:
--spring.profiles.active=8001

// EurekaApplication-8002:
--spring.profiles.active=8002

// EurekaApplication-8003:
--spring.profiles.active=8003

image-20200327022444371

分别启动程序:

EurekaApplication-8001

EurekaApplication-8002

EurekaApplication-8003

浏览器中查看:

image-20200327021754968

image-20200327021723327

集群配置注意事项

如果配置了Eureka集群节点出现在unavailable-replicas下,说明备份节点是不可用的,出现这个问题

的几种原因如下:

  1. eureka.client.serviceUrl.defaultZone 配置项的地址,不能使用localhost,要使用域名,

DNS解析请自行配置。本地可以修改hosts文件来实现。

  1. spring.application.name 属性集群中的每个节点要一致。

  2. 如下两个参数需配为true

      client:
        register-with-eureka: true
        fetch-registry: true
    
  3. 配置 eureka.instance.hostname 属性,设置域名信息

    eureka:
      instance:
        hostname: eureka8003
    
  4. 如果配置了 eureka.instance.prefer-ip-address 属性,应该设置成 false ,或者去掉此参

数,默认就是false。

eureka: 
	instance: 
		prefer-ip-address: false
  1. 查看端口是否被占用了

    // Mac系统
    1.查看端口
    终端输入:lsof -i tcp:port 将port换成被占用的端口(如:80)
    将会出现占用端口的进程信息。
    
    2.kill进程
    找到进程的PID,使用kill命令:kill PID(进程的PID,如2044),杀死对应的进程
    

版权声明:本文为lucaswangdev原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lucaswangdev/p/12578949.html