1.Eureka基础知识:
1.1.引出Eureka:
a.微服务中遇到的问题:
- 1.
order-service
在发起远程调用的时候,该如何得知user-service实例的ip地址和端口? - 2.
order-service
如何得知某个user-service实例是否依然健康
或者是否已经宕机? - 3.有
多个user-service实例地址
,order-service调用时该如何选择
?
b.三大问题及实现解决方式:
问题1:
- 1.
order-service如何得知user-service实例地址
?获取地址信息的流程如下:user-service
服务实例启动后,将自己的信息注册到eureka-server(Eureka服务端
)。这个叫服务注册eureka-server
保存服务名称到服务实例地址列表的映射关系order-service
根据服务名称,拉取实例地址列表
。这个叫服务发现或服务拉取
问题2:
order-service如何从多个user-service实例中选择具体的实例
?
- order-service从实例列表中利用
负载均衡算
法选中一个实例地址 - 向该实例地址发起远程调用
问题3:
order-service如何得知某个user-service实例是否依然健康,是不是已经宕机
?
- user-service会每隔一段时间(
默认30秒
)向eureka-server发起请求,报告自己状态,称为心跳
- 当超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除
- order-service拉取服务时,就能将故障实例排除了
c.什么是服务治理:
- 1.Spring Cloud 封装了
Netflix 公司
开发的 Eureka 模块来实现服务治理 - 2.在传统的
RPC(Dubbo,gRPC,Thirft,Netty)
远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂
,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
。
b.Eureka介绍:
b1.Eureka作用:
- 1.上述这些问题可以使用
SpringCloud中的注册中心来解决
,其中最广为人知的注册中心就是Eureka
- 2.在分布式系统中,不仅仅局限于在注册中心找到服务,与服务地址的映射,还有其他很多问题,比如
服务注册之后,如何及时发现
; 服务宕机之后,如何及时下线
;服务水平如何有效水平扩展 服务发现时;如何进行路由,注册中心如何实现自身的高可用 以上这些‘’;都基于注册中心来解决
。 - 3.Eureka是.Netflix开发的服务注发现组件。它是一个
基于REST的服务
- 4.所谓的注册中心就
相当于是微服务架构的通讯录
,它记录了服务与服务地址的映射关系。 - 5.在分布式架构中,服务就会在注册中心进行注册,当这个
服务需要调用其他服务的时候,就会来注册中心寻找服务地址,进行调用
- 6.总的来说,注册中心的
作用就是:服务注册与服务发现
b2.什么是服务发现与服务注册:
- 1.Eureka
采用了CS的设计架构
,Eureka Server 作为服务注册功能的服务器,它是服务注册中心
; - 2.而系统中的其他微服务,使用
Eureka的客户端
连接到Eureka Server并维持心跳连接
。这样系统的维护人员就可以通过 Eureka Server
来监控系统中各个微服务是否正常运行; - 3.在服务注册与发现中,
有一个注册中心
。当服务器启动的时候,会把当前自己服务器的信息 比如服务地址通讯地址等以别名方式注册到注册中心
上。另一方(消费者|服务提供者
),以该别名的方式去注册中心上获取到实际的服务通讯地址
,然后再实现本地RPC调用
; - 4.
RPC远程调用框架核心设计思想
:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址)); - 5.服务注册中心是以集群的方式进行部署,防止因为只有一台机器而造成的单点故障;
b3.Eureka架构介绍:
- 1.在Eureka架构中,微服务角色有两类:
EurekaServer:服务端,注册中心 和 EurekaClient:客户端
- 2.一个微服务,既可以是服务提供者,又可以是服务消费者,因此eureka
将服务注册、服务发现等
功能统一封装到了eureka-client端
- 3.Eureka在微服务中的角色:
EurekaServer:服务端
- 记录服务信息
- 心跳监控
EurekaClient:客户端
- Provider:服务提供者,例如案例中的 user-service;注册自己的信息到EurekaServer
每隔30秒向EurekaServer发送心跳
- consumer:服务消费者,例如案例中的 order-service;根据服务名称从EurekaServer拉取服务列表
- 基于服务列表做负载均衡,选中一个微服务后发起远程调用
- Provider:服务提供者,例如案例中的 user-service;注册自己的信息到EurekaServer
b4.成员角色介绍:
0
.实例化服务1
.将服务在注册中心进行注册2
.注册中心收录服务 :user-service 127.0.0.1:9091 goods - service 127.0.0.1:9092 sso - service 127.0.0.1 :9093
3
.从注册中心获取服务列表4
.基于负载均衡算法从地址列表选择一个服务地址进行服务调用、5
.服务提供者定期发送心跳6
.检查没有定期发送心跳的服务并在一定时间内剔除服务列表
c.Eureka包含两个组件(Eureka Server
和Eureka Client
)
c1.Eureka Server
提供服务的注册
- 各个微服务节点通过配置启动后,会在
EurekaServer中进行注册
,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息
,服务节点的信息可以在界面中直观看到。
c2.Eureka Client
通过注册中心进行访问
EurekaClient
是一个Java客户端,用于简化EurekaServer的交互
,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器
。- 在应用启动后,将会
向EurekaServer发送心跳(默认周期为30秒)
。 - 如果EurekaServer在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除
(默认90秒)
d.各注册中心的比较:
d1.常见的注册中心:
- 1.Netflix Eureka
- 2.Alibaba Nacos
- 3.HashiCorp Consul
- 4.Apache ZooKeeper
d2.四中注册中心的对比:
3.2.搭建Eurake服务:
a.单机版
Eurake服务
a1.搭建单机版
Eurake服务:
- 1.新建模块:
cloud-eureka-server7001
- 2.改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>cloud2022</artifactId> <groupId>com.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-eureka-server7001</artifactId> <dependencies> <!--eureka-server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- 引入自己定义的api通用包,可以使用Payment支付Entity --> <dependency> <groupId>com.jianqun.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <!--boot web actuator--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--下面是一般通用配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> </project>
- 3.改yml
server: port: 7001 eureka: instance: hostname: eureka7001.com #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: # 设置与Eureka、server交互的地址查询服务和注册服务都需要依赖这个地址 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- 4.主启动类,添加上:
@EnableEurekaServe
r 注解package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @author jianqun * @email:1033586391@qq.com * @creat 2022-02-17-13:29 * * @EnableEurekaServer:说明这是一个服务注册中心 */ @SpringBootApplication @EnableEurekaServer public class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class,args); } }
- 5.测试是否部署成功
a2.把支付服务8001驻进到注册中心EurekaServer端
- 1.改一下主启动,添加:
@EnableEurekaClient
注解package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.ConfigurableApplicationContext; /** * @author jianqun * @email:1033586391@qq.com * @creat 2022-02-09-14:09 */ @SpringBootApplication @EnableEurekaClient public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class,args); } }
- 2.改pom,引入Eureka场景
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-eureka-client</artifactId> </dependency>
- 3.改下yml
server: port: 8001 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包 url: jdbc:mysql://192.168.2.21:3306/db2022?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root eureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: #单机版 defaultZone: http://localhost:7001/eureka mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.atguigu.springcloud.entities # 所有Entity别名类所在包
a3.把支付服务80驻进到注册中心EurekaServer端
- 1.改一下主启动,添加:
@EnableEurekaClient
注解:
package com.jianqun.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class OrderMain8000 {
public static void main(String[] args) {
System.out.println("dddddd");
System.out.println("eeee");
SpringApplication.run(OrderMain8000.class,args);
}
}
- 2.改pom,引入Eureka场景
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-eureka-client</artifactId> </dependency>
- 3.改下yml
- 4.测试发现两个客户端均已经注册到了Eureka服务端上了:
- 4.测试发现两个客户端均已经注册到了Eureka服务端上了:
- 服务启动多个实例的操作方式:
b.集群Eureka构建步骤:
- 1.本节大纲:
b1.Eureka集群原理说明:
b2.EurekaServer集群环境构建步骤:
- 1.参考cloud-eureka-server7001
- 2.新建cloud-eureka-server7002
- 3.改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>mscloud03</artifactId>
<groupId>com.jianqun.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-eureka-server7002</artifactId>
<dependencies>
<!--eureka-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--boot web actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--一般通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
-
4.修改映射配置
- 找到C:\Windows\System32\drivers\etc路径下的hosts文件:
- 修改映射配置添加进hosts文件
127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com
- 找到C:\Windows\System32\drivers\etc路径下的hosts文件:
-
5.写YML(以前单机)
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
- 6.主启动:
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002
{
public static void main(String[] args)
{
SpringApplication.run(EurekaMain7002.class,args);
}
}
b3.将支付服务8001微服务发布到上面2台Eureka集群配置中:
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
b4.将订单服务80微服务发布到上面2台Eureka集群配置中
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
b5.测试01:
- 先要启动EurekaServer,7001/7002服务
- 再要启动服务提供者provider,8001
- 再要启动消费者,80
- 测试:
http://localhost/consumer/payment/get/31
b6.支付服务提供者8001集群环境构建
参考cloud-provider-payment8001
新建cloud-provider-payment8002
改POM
写YML
主启动
业务类
直接从8001粘
修改8001/8002的Controller
8001
8002