Eureka用于服务注册与发现。在多服务间的交互是复杂的,Eureka将注册在其上的服务按key|value存储,能实现负载均衡@loadBalanced以及容错处理——集群保证。回顾
之前通过Rest风格中的RestTemplate实现了两个微服务——支付与订单间的通信。Eureka服务注册与发现
服务与服务间的调用是n对n的关系——》复杂——》服务治理——》EurekaEureka是什么?
Eureka 是 Netflix 开发的,一个基于 REST 服务的,服务注册与发现的组件,以实现中间层服务器的负载平衡和故障转移。
它主要包括两个组件:Eureka Server 和 Eureka Client
-
Eureka Client:一个Java客户端,用于简化与 Eureka Server 的交互(通常就是微服务中的客户端和服务端)
-
Eureka Server:提供服务注册和发现的能力(通常就是微服务中的注册中心)
服务在Eureka上注册,然后每隔30秒发送心跳来更新它们的租约。如果客户端不能多次续订租约,那么它将在大约90秒内从服务器注册表中剔除。注册信息和更新被复制到集群中的所有eureka节点(防止宕机)。来自任何区域的客户端都可以查找注册表信息(每30秒发生一次)来定位它们的服务(可能在任何区域)并进行远程调用。
- Eureka服节点多个,防止宕机。节点间的依赖关系是“互相注册,相互守望”。
- 1个服务的实现也有多个节点,可能存在大量访问请求。——负载均衡。
- 订单和支付两个微服务均在Eureka上注册,再负载均衡到具体的访问地址。
Eureka也相当于是一个服务,那么也从下面6步着手:
- 新建Eureka模块
- 改pom.xml
- 建Yml(application.yml)
- 主启动
- 业务类
- 测试
一、 Eureka注册中心
1、新建cloud-eureka-server7001模块
pom.xml中加入依赖: ——要使用Eureka,当然首先得引入依赖
《! gva只需写ga。 Eureka为server !!!!!!!》 org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.xzq.springcloud cloud-api-commons ${project.version} org.springframework.boot spring-boot org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true
2、resources目录下新建application.yml
《! 微服务的服务端口号必不可少,不然怎么访问localhost:70001/... 。 server.port》
server:
port: 7001
《! 这是真正和Eureka设置相关》
eureka:
instance:
hostname: localhsot #eureka服务端实例名称
client:
register-with-eureka: false #表示不像注册中心注册自己
fetch-registry: false #false表示自己就是注册中心,我的职责就是维护服务实例,并不区检索服务
service-url:
《! 其实就是http://localhost:7001/eureka/ 服务注册与此目录下》
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3、编写启动类EurekaApplication7001
package com.xzq.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
《!主启动类@SpringBootApplication注解必不可少。 @EnableEurekaServer开启Server服务》
@SpringBootApplication
@EnableEurekaServer//开启EurekaServer
public class EurekaApplicatin7001 {
《!主启动类里面就注解和主函数入口。 mainboot快捷键。 参数填当前类.class》
public static void main(String[] args) {
SpringApplication.run(EurekaApplicatin7001.class, args);
}
}
二、支付微服务8001入驻7001
1、pom.xml添加
《! 这里就是Eureka的client端啦》 org.springframework.cloud spring-cloud-starter-netflix-eureka-client
2、改application.yml
eureka:
client:
register-with-eureka: true #表示向注册中心注册自己 默认为true
fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
service-url:
defaultZone: http://localhost:7001/eureka/ # 入驻地址
3、启动类加上注解@EnableEurekaClient
三、订单微服务80入驻7001
同上
**原理说明** 服务注册:将服务信息注册到注册中心 服务发现:从注册中心获取服务信息 实质:存key服务名,取value调用地址 **步骤** 1. 先启动eureka注册中心 2. 启动服务提供者payment支付服务 3. 支付服务启动后,会把自身信息注册到eureka 4. 消费者order服务在需要调用接口时,使用服务别名去注册中心获取实际的远程调用地址 5. 消费者获得调用地址后,底层实际是调用httpclient技术实现远程调用 6. 消费者获得服务地址后会缓存在本地jvm中,默认每30秒更新异常服务调用地址
问题:微服务RPC远程调用最核心的是高可用,如果注册中心只有一个,出现故障就麻烦了。会导致整个服务环境不可用。
解决办法:搭建eureka注册中心集群,实现负载均衡+故障容错
互相注册,相互守望——宗旨
集群搭建步骤
1、依照7001新建7002,除了主启动类和yml配置文件改,其他都一样 2、修改C:WindowsSystem32driversetc下的hosts 末尾加上 # springcloud2020 127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.com 3、修改7001项目 applicaton.yml server: port: 7001 eureka: instance: hostname: eureka7001.com #eureka服务端实例名称 client: register-with-eureka: false #表示不向注册中心注册自己 fetch-registry: false #false表示自己就是注册中心,我的职责就是维护服务实例,并不区检索服务 service-url: 《! 这就是相互注册》 defaultZone: http://eureka7002.com:7002/eureka/ 4、修改7002(也需要相互注册) server: port: 7002 eureka: instance: hostname: eureka7002.com #eureka服务端实例名称 client: register-with-eureka: false #表示不向注册中心注册自己 fetch-registry: false #false表示自己就是注册中心,我的职责就是维护服务实例,并不区检索服务 service-url: defaultZone: http://eureka7001.com:7001/eureka/ 5、eurekaserver集群效果
6、支付和订单两个微服务注册到eureka集群
修改80项目yml配置文件service-url:
#defaultZone: http://localhost:7001/eureka/ # 入驻地址
《!这里就是两个Eureka节点都要注册啦》
defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7001.com:7001/eureka/
7、8001同理
8、启动7001、7002再启动8001、80项目查看效果
搭建支付服务集群
1. 参照8001搭建8002服务
直接访问localhost:8001/payment/get/1
结果:{"code":200,"message":"查询数据成功,serverport:8001","data":{"id":1,"serial":"尚硅谷"}}
访问localhost:8002/payment/get/1
结果:{"code":200,"message":"查询数据成功,serverport:8002","data":{"id":1,"serial":"尚硅谷"}}
成功
****consumer访问时,第2个支付服务不起作用!!!****
访问localhostpayment/get/1
结果:{"code":200,"message":"查询数据成功,serverport:8001","data":{"id":1,"serial":"尚硅谷"}}
**但是会发现 ,每次范文都是8001端口**
原因是再80项目的controller层中,我们将请求路径写死了。
修改如下:
public class OrderController {
// private final static String PAYMENT_URL = "http://localhost:8001";
《!改为通过服务名称访问》
private final static String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
但是访问localhost/consumer/payment/get/1会出现500错误,原因是,****!!我们配置了以服务名的方式访问,但不能确定是哪一个服务。!!****
2. 我们需要给restTemplate开启负载均衡,默认是轮循。
《! 修改配置类》
@Configuration
public class ApplicationContextConfig {
@Bean
《! 开启》
@LoadBalanced//开启负载均衡
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}



