一、微服务简介

1、什么是微服务?

微服务架构是分布式架构中的一种。
微服务(MicroService)的概念最早是在 2014 年由 Martin Fowler 和 James Lewis 共同提出,他们定义了微服务是由单一应用程序构成的小服务,拥有自己的进程与轻量化处理,服务依业务功能设计(微服务一个业务一个项目),以全自动方式部署,与其他服务使用特性的通讯协议(如:HTTP或RPC等)(每个项目都是一个标准的web项目)。同时,服务会使用最小规模的集中管理 (例如 Docker)技术,服务可以用不同的编程语言与数据库等。
提取出的核心点:
1. 微服务是架构,发展到现在微服务已经可以说是综合平台(架构以外还包含服务治理、注册中心、服务容灾等相关特性)。
2. 微服务中项目都称为服务。
3. 微服务拆分颗粒度为业务。
4. 微服务中服务和服务之间使用特定协议通信(如:HTTP、PRC)。
5. 微服务和Docker结合使用更方便。
6. 微服务是分布式架构的一种。

2、应用程序架构变迁图

SOA架构、微服务架构统称为分布式架构。
Netflix Eureka服务发现工具 - 图1

2.1 SOA架构和微服务架构的区别?

SOA架构: 核心消息总线。消息总线过于笨重在目前项目中已经很少使用了。在SOA架构中每个项目都满足分布式要求,分别部署到不同的服务器上。拆分颗粒度是模块。
微服务服务架构:核心是把项目拆分成多个小服务,每个服务几天的时间就可以测试上线,版本迭代。在微服务架构中不要求每个服务独占一台服务器。可以结合Docker等技术把多个服务部署到一台服务器上。拆分颗粒度业务。

2.2 目前市场上微服务架构的常用实现框架

实现框架:Spring Cloud。
Spring Cloud里面目前包含三体体系:

  • Spring Cloud Netflix : 学习这个。目前市场上使用最多的。
  • Spring Cloud Alibaba:基于Dubbo实现的。
  • Spring 其他:为了摆脱受Netflix公司限制,逐渐推出一套组件。

    3、Spring Cloud下三个阵营对比


    Netflix Eureka服务发现工具 - 图2

    二、Spring Cloud简介

    Spring Cloud是Spring旗下的一个顶级项目。它没有具体内容,但里面包含了很多二级子项目,Spring Cloud就是这些二级子项目的统称。
    Spring Cloud包含了很多二级子项目,每个二级子项目都有对应的功能,所以Spring Cloud整体包含的功能是比较强大。
    我们主要学习的是Spring Cloud Netflix相关框架。
    强调:Spring Cloud是完全基于Spring Boot的。官方文档中就没有XML配置版本。

    1、Netflix简介

    Netflix(Nasdaq NFLX) 成立于1997年,是一家在线影片租赁提供商,主要提供Netflix超大数量的DVD并免费递送,总部位于美国加利福尼亚州洛斯盖图。
    Spring Cloud集成时会把Netflix的软件进行打包成一个依赖,我们项目依赖了对应的jar,可以直接使用这个软件,免去了软件安装的过程(这也是Spring Cloud非常大的优点)

    三、Spring Cloud版本号说明

    1、常见版本号说明

    开发中,使用的框架版本,最好是RELEASE版本或Final版本。
    常见版本号格式为: x.y.z.stage
    x - 数字格式主版本号,当功能模块有较大更新或者整体架构发生变化时,主版本号会更新。
    y - 数字格式次版本号,次版本表示只是局部的一些变动。
    z - 数字格式修正版本号,一般是bug的修复或者是小的变动。
    stage - 希腊字母版本号,也称为阶段版本号。用于标注当前版本的软件处于哪个开发阶段。常用的阶段版本包括:BASE、ALPHA、BATE、RELEASE/FINAL。
    BASE - 设计阶段。只有相应的设计没有具体的功能实现。
    ALPHA - 软件的初级版本。存在较多的bug。
    BATE - 表示相对ALPHA有了很大的进步,消除了严重的bug,还存在一些潜在的bug。
    RELEASE/FINAL - 该版本表示最终版,即正式发布版本。

    2、Spring Cloud版本号说明

    版本号命名:Spring Cloud主框架版本号是使用英国伦敦地铁站名称来进行标记的,并根据地铁站名称的首字母的英文自然升序排列来识别版本的递增。如:Angle、Brixton、Camden、Dalston、Edgware、Finchley、Greenwich 、Hoxton等。后续版本提升会继续根据首字母升序排列。
    要注意:Spring Cloud是基于Spring Boot,不同的Spring Cloud要使用不同的Spring Boot版本。使用Spring Cloud H版本建议使用的是2.2.x不能使用2.3.x版本,如果使用2.3.x可能出现问题。
    Netflix Eureka服务发现工具 - 图3
    附:Spring Data的版本命名也是和Spring Cloud一样的,Spring Data版本使用字母命名,里面子项目使用数字命名。因为Spring Data和Spring Cloud都是一些列框架的统称。

    四、Eureka简介

    1、Eureka是什么

    Eureka是由Netflix公司推出的服务注册和发现工具(Service Discovery,平时说的注册中心/服务治理)。现已被Spring Cloud集成,提供了开箱即用的支持。(直接在项目中直接集成,快捷使用)

    2、包含注册中心的软件简易架构图

    image.png
    注册中心在项目中的意义:
    实现应用程序解耦。项目之间不是直接进行项目通信。项目A把自己服务器的IP、端口等信息注册中注册中心中,项目B从注册中心中获取项目A的信息后再进行访问项目A。
    项目发布所在服务器地址可以随意变化。如果在项目B中进行编码写项目A的IP和端口,当项目A的服务器地址发生变化或项目A重新部署到其他服务器上时,重新编码项目B中IP和端口。
    借助注册中心可以实现负载均衡等效果。

    3、Eureka角色

    Eureka中分为两个角色:Eureka Server(Eureka服务)和Eureka Client(Eureka客户端)。
    无论是服务端还是客户端其本质都是一个Java项目,在Spring Cloud中主要通过启动类上添加@EnableEurekaServer和@EnableEurekaClient(可以省略)来区分当前应用程序是服务端还是客户端。
    Eureka Server可以理解成之前我们讲解的Zookeeper注册中心,只是现在使用的是Java项目实现的(Spring Cloud内嵌Eureka)。
    Eureka Client 可以理解成所有需要注册到Eureka Server中的项目。为什么需要向注册中心中注册呢?因为注册后别人才能通过注册中心获取到项目信息和项目所在服务器信息,通过这些信息调用这个项目。Spring Cloud中每个项目调用的信息都存储在了注册中心中(Eureka)。
    注意:在这里,Spring Cloud中没有Provider和Consumer说法。如果A项目访问B项目,称A项目为Application Client,称B项目为Application Service。同时可能存在C访问A的情况,这是C项目是Application Client,A项目是Application Service。发现A项目又是Application Service又是Application Client,主要看针对哪个业务场景。无论是Applicatin Service还是Application Client都是Eureka Client。

    五、Eureka满足的CAP的定理

    在Spring Cloud Netfilx中使用Eureka作为注册中心。

    1、CAP理论(分布式一致性定理)

    著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。而Eureka则是AP
    C(一致性Consistency):在分布式系统完成某写操作后任何读操作,都应该获取到该写操作写入的那个最新的值。相当于要求分布式系统中的各节点时时刻刻保持数据的一致性。
    A(可用性Availability):在分布式系统中,意思是只要收到用户的请求,服务器就必须给出回应。用户角度来看就是不会出现系统操作失败或者访问超时等问题。
    P(分区容错性):指的分布式系统中的某个节点或者网络分区出现了故障的时候,整个系统仍然能对外提供服务。也就是说部分故障不影响整体使用。
    事实上我们在设计分布式系统是都会考虑到bug,硬件,网络等各种原因造成的故障,所以即使部分节点或者网络出现故障,我们要求整个系统还是要继续使用的
    (不继续使用,相当于只有一个分区,那么也就没有后续的一致性和可用性了)
    CAP三者不可兼得,该如何取舍:
    (1) CA: 优先保证一致性和可用性,放弃分区容错。 这也意味着放弃系统的扩展性,系统不再是分布式的,有违设计的初衷。
    (2) CP: 优先保证一致性和分区容错性,放弃可用性。在数据一致性要求比较高的场合(譬如:zookeeper,Hbase) 是比较常见的做法,一旦发生网络故障或者消息丢失,就会牺牲用户体验,等恢复之后用户才逐渐能访问。
    (3) AP: 优先保证可用性和分区容错性,放弃一致性。NoSQL中的Cassandra 就是这种架构。跟CP一样,放弃一致性不是说一致性就不保证了,而是逐渐的变得一致。

    六、第一个Eureka Server

    搭建Eureka Server时就相当于在安装Eureka软件(在Spring Cloud学习的一种全新方式,替换了之前需要安装对应软件的问题)。

    1、 导入依赖

    添加Spring Boot 依赖和Spring Cloud集成的Eureka Server依赖。
    所有依赖的版本都是最新版。 ```xml org.springframework.boot spring-boot-starter-parent 2.3.9.RELEASE org.springframework.cloud spring-cloud-dependencies Hoxton.SR10 pom import org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-server
  1. <a name="TJiJK"></a>
  2. ### 2、编写配置文件
  3. 在application.yml中添加一下内容,不添加会报错。<br />此处要求tomcat端口和Eureka Server的端口是相同的。Eureka Server 默认端口是8761所以此处配置为8761.如果此处希望配置为8082等非8761端口,需要打开注释。
  4. | **eureka**:<br /> **client**:<br /> _# 因为当前项目为服务,不需要向服务注册自己,默认为true<br /> _**register-with-eureka**: **false<br /> **_# 因为当前为非集群版eureka,所以不需要同步其他节点数据<br /> _**fetch-registry**: **false<br /> **_# 当server.port配置不是8761时需要配置内容 # service-url:<br /># defaultZone: _[_http://localhost:${server.port}/eureka/_](http://localhost:$%7Bserver.port%7D/eureka/)<br />__ _**server**:<br /> **port**: 8761 |
  5. | --- |
  6. <a name="pUsMf"></a>
  7. ### 3、在启动类中添加注解
  8. 在启动类中添加@EnableEurekaServer注解,表示当前项目为Eureka Server
  9. | @SpringBootApplication<br />@EnableEurekaServer<br /> **public class **MyApplication {<br /> **public static void **main(String[] args) {<br /> SpringApplication._run_(MyApplication.**class**,args);<br /> }<br />} |
  10. | --- |
  11. <a name="dcEC3"></a>
  12. ### 4、访问
  13. 在浏览器地址栏输入:[http://localhost:8761/](http://localhost:8080/)<br />![](https://cdn.nlark.com/yuque/0/2021/png/22310212/1636866586196-8aa609f4-234a-4a43-a973-2e0bfa1b2491.png#height=143&id=tRsLM&originHeight=469&originWidth=1357&originalType=binary&ratio=1&status=done&style=none&width=415)
  14. <a name="yXSd9"></a>
  15. ## 七、Eureka 服务管理平台介绍
  16. <a name="x6wnv"></a>
  17. ### 1、Eureka Server服务管理平台访问预览
  18. ![](https://cdn.nlark.com/yuque/0/2021/png/22310212/1636866586523-3231e41c-d294-4b04-b65b-5229696d74e4.png#height=267&id=dpJ9z&originHeight=857&originWidth=1334&originalType=binary&ratio=1&status=done&style=none&width=415)
  19. <a name="Sdzc7"></a>
  20. ### 2、System Status
  21. 系统状态展示
  22. <a name="FFeIK"></a>
  23. ### 3、DS Replicas
  24. 注册中心集群列表
  25. <a name="wPfKV"></a>
  26. ### 4、Instances currently registered with Eureka
  27. 已在注册中心中注册的服务列表
  28. <a name="NHcKn"></a>
  29. ### 5、General Info
  30. 当前注册中心相关信息展示
  31. <a name="rPjBH"></a>
  32. ### 6、Instance Info
  33. 当前注册中心实例信息展示
  34. <a name="NxEIu"></a>
  35. ## 八、第一个Eureka Client
  36. Eureka Client可以向Eureka Server中注册自己。
  37. <a name="moD8m"></a>
  38. ### 1、导入依赖
  39. 注意依赖换成了Eureka客户端依赖。
  40. ```xml
  41. <parent>
  42. <groupId>org.springframework.boot</groupId>
  43. <artifactId>spring-boot-starter-parent</artifactId>
  44. <version>2.3.9.RELEASE</version>
  45. </parent>
  46. <dependencyManagement>
  47. <dependencies>
  48. <dependency>
  49. <groupId>org.springframework.cloud</groupId>
  50. <artifactId>spring-cloud-dependencies</artifactId>
  51. <version>Hoxton.SR10</version>
  52. <type>pom</type>
  53. <scope>import</scope>
  54. </dependency>
  55. </dependencies>
  56. </dependencyManagement>
  57. <dependencies>
  58. <dependency>
  59. <groupId>org.springframework.boot</groupId>
  60. <artifactId>spring-boot-starter-web</artifactId>
  61. </dependency>
  62. <dependency>
  63. <groupId>org.springframework.cloud</groupId>
  64. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  65. </dependency>
  66. </dependencies>

2、编写配置文件

在配置文件中添加配置。
1. 此处端口就是为了和其他项目不冲突而定的一个端口。
2. spring.application.name为注册到eureka server后的名字。名字中不能使用下划线,否则可能出现无法注册的问题。
3. 如果Eureka Server配置的Server.port不是8761需要打开下面的注释,并且把url中端口号改成Eureka server中defaultZone配置的端口号。如果Eureka Server的端口是8761,注释部分就可以省略。

# 此处应该定义名称,否则注册到Server后的名字为UNKNOWN
spring:
application:
name: eureka-client
#eureka:
# client:
# serviceUrl:
# defaultZone: http://localhost:8761/eureka/

3、编写启动类

启动类上的注解@EnableEurekaClient是可以省略的,平时不编写。

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

4、观察结果

通过Eureka Server的可视化界面观察Eureka Client是否注册成功。如果注册成功会在页面中显示注册的client信息。
Application: 配置文件中定义的应用程序名称
Status:UP表示正在执行,smallming客户端所在服务器的主机名,eureka-client定义应用程序名称,如果是8080端口省略,如果不是会显示在后面
Netflix Eureka服务发现工具 - 图5

九、Eureka集群实现原理

9.1官方原理图

Netflix Eureka服务发现工具 - 图6

9.2解释说明

所有Eureka Server 通过Replicate进行数据同步。无论Eureka Client向哪个Eureka Server中注册信息,最终所有Eureka Server中都会存储注册的信息,这些信息都缓存到Eureka Server的本地。每个Eureka Server中同步后的数据都是完全相同的。
Eureka Client向Eureka Server注册信息的时候我们称它为Application Service,当获取注册的信息时称为Application Client,由于可能出现某个Eureka Client即需要注册服务,又需要获取其他服务,所以很多Eureka Client既是Application Service 又是Application Client。
(保证Eureka中存储信息有效性手段)Eureka Client启动后,每隔30秒向Eureka Server发送一次心跳,证明自己的可用,可通过Netflix Eureka服务发现工具 - 图7修改心跳的间隔时间。当Eureka Server超过90秒没有收到提供者的心跳后,会认为这个提供者已经宕机,销毁实例。可以通过Netflix Eureka服务发现工具 - 图8修改时间。
如果重新启动Eureka Server,会销毁所有实例。

9.3自我保护机制

Eureka中有一种自我保护机制。当15分钟内超过85%的Eureka Client都没有正常的心跳包时,Eureka认为Eureka Server和Eureka Client之间出现了网络问题。这个时候将不在因为没有收到心跳而销毁实例。Eureka Client依然可以访问Server,但是Server不会把内容同步到其他Server中。当网络稳定后,Server会把注册的信息同步到其他Server中。
在Eureka中自我保护机制默认为开启的:
Netflix Eureka服务发现工具 - 图9

9.4关闭自我保护

eureka:
server:
# 关闭自我保护
enable-self-preservation: false
# 扫描失效服务的时间间隔
eviction-interval-timer-in-ms: 10000

5、Eureka保证AP

在Eureka集群中所有的节点都是保存完整的信息的,当Eureka Client向Eureka中注册信息时,如果发现节点不可用,会自动切换到另一台Eureka Sever,也就是说整个集群中即使只有一个Eureka可用,那么整个集群也是可用的。
同时Eureka的自我保护机制也是实现可用性非常重要的体现。

十、 Eureka高可用集群搭建

最终效果:
编写一个项目通过不同的配置文件加载不同参数。
最后把集群部署到服务器上。集群设定有两个Eureka Server,每个Eureka Server安装到不同的服务器上。

1、添加依赖

在集群中依赖和单机版依赖是完全相同的。
为了后面打包发布到服务器中,所以同时也导入了Spring Boot打包插件。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.9.RELEASE</version>
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR10</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

2、创建配置文件

Eureka集群可以使用Spring Boot多配置文件实现。集群中创建几个Eureka Server就编写几个配置文件。
Netflix Eureka服务发现工具 - 图10
Eureka集群是通过IP相互访问的。(可以通过域名项目访问)

| eureka:
client:
service-url:
defaultZone: http://192.168.58.252:8761/eureka/

#这个属性不配是不可以通过IP相互访问的默认使用域名 instance:
prefer-ip-address: true
server
:
port: 8761
spring:
application:
name: eurekaserver1 | | —- | | eureka:
client:
service-url:
defaultZone: http://192.168.8.129:8761/eureka/

instance:
prefer-ip-address: true
server
:
port: 8761
spring:
application:
name: eurekaserver2 |

3、编写启动器

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

4、打包

使用IDEA中MAVEN的install命令进行打包
Netflix Eureka服务发现工具 - 图11
打包后在项目的target中出现打包后的jar
Netflix Eureka服务发现工具 - 图12

5、使用命令运行

把eureka1-1.0-SNAPSHOT.jar上传到LINUX服务器中。使用命令运行java -jar -Dspring.profiles.active=配置文件变量名 打包后jar包名称
注意:SpringBoot支持其他文件名称访问如果yml名称叫application-linux.yml
yml的名称只可以叫application-xxx.yml 不可以叫其他名称
运行为:java -jar -Dspring.profiles.active=linux eureka1-1.0-SNAPSHOT.jar

java -jar -Dspring.profiles.active=eurekaserver1 eureka1-1.0-SNAPSHOT.jar

6、测试集群效果

可以观察两个Eureka中数据同步
Netflix Eureka服务发现工具 - 图13Netflix Eureka服务发现工具 - 图14

7、向集群中注册Eureka Client

修改上面编写的第一个Eureka Client项目的配置文件。
写在defaultZone中优先向第一个URL注册自己,如果不可用才向第二个注册自己。

eureka:
client:
service-url:
defaultZone: http://eurekaserver1:8761/eureka/,http://eurekaserver2:8761/eureka/

8附加操作:(如果想配置域名操作如下即可)

8.1配置文件

.yml配置文件更改

instance: hostname: eurekaserver1

8.2配置域名解析

修改Linux服务器中/etc/hosts文件。每行前面的ip是jar所在服务器的ip,后面的名称是项目中配置文件配置的hostname值

192.168.8.130 eurekaserver1
192.168.8.131 eurekaserver2

8.3修改windows的域名解析

修改C:\Windows\System32\drivers\etc\hosts文件

192.168.8.137 eurekaserver1
192.168.8.136 eurekaserver2


十一、 Eureka优雅关机

注意:Actuator和Eureka没有任何关系。放在这除了实现Eureka关机的效果以外,更重要是给同学们讲解Actuator的用法。
可以借助Spring Boot提供的Actuator(监视器,监控中心)实现Eureka的优雅关机。
Spring Cloud 基于Spring Boot,Actuator关闭Spring Boot项目,SpringBoot项目都关闭了,Eureka Server项目也关闭了。
spring-cloud-starter-netflix-eureka-server默认依赖了Actuator,就不需要导入额外包。正常是需要导入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>


在配置文件中开启shutdown功能即可。

management:
endpoints:
# 所有功能默认开启
enabled-by-default: true
# 显示所有已启用功能
web:
exposure:
include: ‘*’

Actuator中所有功能只提供了post方式方式。
使用postman发送POST请求
http://localhost:8761/actuator/shutdown