springcloudeureka(springcloudeureka原理)

本篇文章给大家谈谈springcloudeureka,以及springcloudeureka原理对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Spring Cloud Eureka服务注册中心

服务治理:Spring Cloud Eureka

Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,它基于Netflix

Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能。Spring Cloud通过为

Eureka增加了Spring Boot风格的自动化配置,我们只需通过简单引入依赖和注解配置就能

让Spring Boot构建的微服务应用轻松地与Eureka服务治理体系进行整合。

在本章中,我们将指引读者学习下面这些核心内容,并构建起用于服务治理的基础设

施。

·构建服务注册中心

·服务注册与服务发现

。Eureka的基础架构

Eureka的服务治理机制

Eureka的配置

服务治理

服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务

实例的自动化注册与发现。为什么我们在微服务架构中那么需要服务治理模块呢?微服务

系统没有它会有什么不好的地方吗?

在最初开始构建微服务系统的时候可能服务并不多,我们可以通过做一些静态配置来

完成服务的调用。比如,有两个服务A和B,其中服务A需要调用服务B来完成一个业务

操作时,为了实现服务的高可用,不论采用服务端负载均衡还是客户端负载均衡,都需

要手工维护服务的具体实例清单。但是随着业务的发展,系统功能越来越复杂,相应一下的

微服务应用也不断增加,我们的静态配置就会变得越来越难以维护。并且面对不断发展的

业务,我们的集群规模、服务的位置、服务的命名等都有可能发生变化,如果还是通并蚂消过手

工维护的方式,那么极易发生错误或是命名冲突等间题。同时,对于物数这类静态内容的维护

为了解决微服务架构中的服务实例维护问题,产生了大量的服务治理框架和产品。这

也必将消耗大量的人力。

些框架和产品的实现都围绕着服务注册与服务发现机制来完成对微服务应用实例的自动化

管理。

服务注册:在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册

中心登记自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告

知注册中心,注册中心按服务名分类组织服务清单。比如,我们有两个提供服务A

的进程分别运行于192.168.0.100:8000和192.168.0.101:8000位置上,

另外还有三个提供服务B的进程分别运行于192.168.0.100:9000、

192.168.0.101:9000、192.168.0.102:9000位置上。当这些进程均启动,

并向注册中心注册自己的服务之后,注册中心就会维护类似下面的一个服务清单。

另外,服务注册中心还需要以心跳的方式去监测清单中的服务是否可用,若不可用

需要从服务清单中剔除,达到排除故障服务的效果。

服务名

位置

服务A

192.168.0.100:8000、192.168.0.101:8000

服务B

192.168.0.100:9000、192.168.0.101:9000、192.168.0.102:9000

服务发现:由于在服务治理框架下运作,服务间的调用不再通过指定具体的实例地

址来实现,而是通过向服务名发起请求调用实现。所以,服务调用方在调用绝知服务提

供方接口的时候,并不知道具体的服务实例位置。因此,调用方需要向服务注册中

心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。比如,

现有服务C希望调用服务A,服务C就需要向注册中心发起咨询服务请求,服务注

册中心就会将服务A的位置清单返回给服务C,如按上例服务A的情况,C便获得

了服务A的两个可用位置192.168.0.100:8000和192.168.0.101:8000。

当服务要发起调用的时候,便从该清单中以某种轮询策略取出一个位置来进行服

务调用,这就是后续我们将会介绍的客户端负载均衡。这里我们只是列举了一种简

单的服务治理逻辑,以方便理解服务治理框架的基本运行思路。实际的框架为了性

能等因素,不会采用每次都向服务注册中心获取服务的方式,并且不同的应用哦场景

在缓存和服务剔除等机制上也会有一些不同的实现策略。

[img]

Spring Cloud之Eureka源码分析2

本章主要姿滑介绍Eureka Client端源码分析。

客户端主要是向Server服务端发送Http请求,主要有注册,心跳续约,获取注册信息等功能

在分析源码之前,需要查看下客户端配置文件

application.yml

访问服务端localhost:8000的注册信息

自动配置类,首先要从依赖包的spring.factories文件看起

其中最重要的是EurekaClientAutoConfiguration类

只要类中存在EurekaClientConfig类所在段带的依赖包eureka-client-xx.jar就可以加载这个类

2、RefreshableEurekaClientConfiguration 用来开启定时任务

1、EurekaAutoServiceRegistration

实例化EurekaAutoServiceRegistration对象,并放到spring容器中

org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration

2、start

由于EurekaAutoServiceRegistration类实现了SmartLifecycle,SmartApplicationListener等接口,所以会在容器初始化完成之后调用EurekaAutoServiceRegistration#start方法。

调用ApplicationInfoManager应用信息管理设置实例初始化状态信息initialStatus

4、setInstanceStatus

com.netflix.appinfo.ApplicationInfoManager#setInstanceStatus

设置实例迹燃腊状态信息并调用监听器notify方法

com.netflix.discovery.DiscoveryClient#register

这里就到了注册客户端的地方

包括缓存更新与心跳续约,通过RefreshableEurekaClientConfiguration类开始初始化,并最终通过initScheduledTasks方法开启定时调度器任务

EurekaClientAutoConfiguration.RefreshableEurekaClientConfiguration

这个类是程序实现定时刷新任务开始的地方,主要是通过new CloudEurekaClient()方法创建Cloud客户端类(CloudEurekaClient)

下面主要查看CloudEurekaClient的调用链

1、CloudEurekaClient#CloudEurekaClient

org.springframework.cloud.netflix.eureka.CloudEurekaClient#CloudEurekaClient

调用CloudEurekaClient类的父类,和对applicationInfoManager、publisher、eurekaTransportField等属性值赋值

2、DiscoveryClient#DiscoveryClient

com.netflix.discovery.DiscoveryClient#DiscoveryClient

4、DiscoveryClient#DiscoveryClient

定义调度器类、心跳执行器和缓存刷新执行器等的定义。

com.netflix.discovery.DiscoveryClient#DiscoveryClient

这个方法主要流程:

①、这个方法前半部分是初始化属性值。

②、根据客户端client配置文件,config.shouldFetchRegistry()是否获取注册表信息和

config.shouldRegisterWithEureka()是否注册到eureka上来对属性赋值,或直接返回

③、初始化调度器scheduler、两个线程池执行器heartbeatExecutor(心跳续约)和cacheRefreshExecutor(缓存刷新,定时获取注册信息表)

④、在获取服务注册信息条件下,没有获取到信息或异常即fetchRegistry(false)返回false。可以从备用服务器获取调用fetchRegistryFromBackup()方法,内部实现方法调用备用服务器类的get方法backupRegistryProvider.get()

⑤、初始化调度器任务方法initScheduledTasks()

调度器任务包括:

1、定时刷新缓存注册表信息,分为全量获取和增量获取

2、定时向服务端发送心跳续约

3、状态改变监听器执行

这里不仅包括这些定时任务,注册也是在这里调用状态改变监听器StatusChangeListener的notify方法

com.netflix.discovery.DiscoveryClient#initScheduledTasks

1、initScheduledTasks

com.netflix.discovery.DiscoveryClient#initScheduledTasks

TimedSupervisorTask继承了TimerTask,TimerTask实现了Runnable

TimedSupervisorTask类的构造方法

2、HeartbeatThread

执行TimedSupervisorTask的task任务,在给定的间隔内执行心跳续约任务

com.netflix.discovery.DiscoveryClient.HeartbeatThread

3、renew

续约任务,续约成功更新lastSuccessfulHeartbeatTimestamp参数。通过REST方式进行续订

com.netflix.discovery.DiscoveryClient#renew

服务端调用到renewLease方法续约,appName和id与客户端传过来的相同

com.netflix.eureka.resources.InstanceResource#renewLease

在定时刷新缓存实现获取注册信息,分为全量拉取和增量拉取

创建TimedSupervisorTask调度任务类,传入cacheRefreshExecutor执行器、CacheRefreshThread任务类、从服务端获取注册信息的时间间隔RegistryFetchIntervalSeconds等参数信息

全量拉取条件(任意一个)

①、disable-delta属性值是true 关闭增量拉取

②、registry-refresh-single-vip-address 属性vip地址的值不为空

③、forceFullRegistryFetch 为true 传过来的变量值

④、localRegionApps的applications是null 当前区域应用

⑤、applications的数量是0

⑥、applications的版本是-1

实现增量拉取的条件是不符合全量拉取,调用getAndUpdateDelta方法

com.netflix.discovery.DiscoveryClient#getAndUpdateDelta

这个方法实现了增量拉取的请求实现,及对拉取增量结果的处理

1、getDelta

eurekaTransport.queryClient.getDelta(remoteRegionsRef.get())的具体实现是通过AbstractJerseyEurekaHttpClient类实现的

com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient#getDelta

这个方法主要是遍历recentlyChangedQueue存在的数据放入到Applications对象中。所以recentlyChangedQueue队列中存在什么数据就很重要,因此我们需要了解最新更新队列recentlyChangedQueue是如何放入的及放入那些数据,及其的移除的原理。

在这个方法最后 apps.setAppsHashCode设置了当前服务端所有注册信息的HashCode,所以这个增量对象存储了最新的状态HashCode值。

7、客户端获取增量数据的处理

还是在getAndUpdateDelta方法内,对服务端传输过来数据,获取当前服务端的增量数据部分

com.netflix.discovery.DiscoveryClient#getAndUpdateDelta

这个方法的主要过程是:

如果增量数据部分为空,则执行全量拉取。

对当前服务的注册信息表执行updateDelta(delta)方法,对当前注册实例的增加删除或修改操作

当前更新后的服务注册表的HashCode值与增量对象存储的最新的状态HashCode值比较,如果不相等 则执行全量拉取

最新更新队列ConcurrentLinkedQueueRecentlyChangedItem recentlyChangedQueue

com.netflix.eureka.registry.AbstractInstanceRegistry#AbstractInstanceRegistry类在构建创建注册表时创建了recentlyChangedQueue队列,并创建了一个增量调度任务方法getDeltaRetentionTask方法

com.netflix.eureka.registry.AbstractInstanceRegistry#getDeltaRetentionTask

对recentlyChangedQueue队列中对最近改变的队列在一定时间范围retentionTimeInMSInDeltaQueue=180000ms(3分钟)外的进行定时清除(30s清除一次)

3、statusUpdate

4、deleteStatusOverride

getDeltaRetentionTask进行定时清除

全量拉取与增量拉取过程类似

全量拉取调用getAndStoreFullRegistry方法

1、getAndStoreFullRegistry

com.netflix.discovery.DiscoveryClient#getAndStoreFullRegistry

2、getApplications

com.netflix.discovery.shared.transport.EurekaHttpClient#getApplications

SpringCloud之Eureka Feign简介

1、Eureka注册中心

现在公司项目大多采用前后端分没拆敏离架构,服务层被拆分成了很多的微服务,为方便管理Spring Cloud给我们提供了服务注册中心来管理微服务。枯枝

1.1、Eureka简介

Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提

供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和

客户端均采用Java语言编写。下图显示了Eureka Server与Eureka Client的关系:

Eureka Server是服务端,负责管理各各微服务结点的信息和状态。

在微服务上部署Eureka Client程序,远程御如访问Eureka Server将自己注册在Eureka Server。

微服务需要调用另一个微服务时从Eureka Server中获取服务调用地址,进行远程调用。

1.2、Eureka Server搭建

1.2.1、单机环境搭建

1、父工程引入Maven依赖:

org.springframework.cloud

spring‐cloud‐dependencies

Finchley.SR1

pom

import

2、在Eureka Server工程添加:

org.springframework.cloud

spring‐cloud‐starter‐netflix‐eureka‐server

3、在SpringBoot启动类添加@EnableEurekaServer注解,标识这是一个Eureka服务:

@EnableEurekaServer//标识这是一个Eureka服务

@SpringBootApplication

publicclassGovernCenterApplication{

publicstaticvoidmain(String[] args){

        SpringApplication.run(GovernCenterApplication.class, args);

    }

}

4、在application.yml中配置Rureka:

server:

port:50101#服务端口

spring:

application:

name:xc‐govern‐center#指定服务名

eureka:

client:

registerWithEureka:false#服务注册,是否将自己注册到Eureka服务中

fetchRegistry:false#服务发现,是否从Eureka中获取注册信息

serviceUrl:#Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)

defaultZone:

server:

enable‐self‐preservation:false#是否开启自我保护模式,开发模式建议关闭

eviction‐interval‐timer‐in‐ms:60000#服务注册表清理间隔(单位毫秒,默认是60*1000)

5、启动Eureka Server,浏览50101端口:

上图红色提示信息:

THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF

NETWORK/OTHER PROBLEMS.

自我保护模式被关闭。在网络或其他问题的情况下可能不会保护实例失效。

Eureka Server有一种自我保护模式,当微服务不再向Eureka Server上报状态,Eureka Server会从服务列表将此

服务删除,如果出现网络异常情况(微服务正常),此时Eureka server进入自保护模式,不再将微服务从服务列

表删除。

至此,Eureka服务端已经搭建完成,下面进行服务注册,将微服务注册到Eureka服务端进行管理。

1.3、服务注册

1、在需要注册的微服务中,添加依赖:

org.springframework.cloud

spring‐cloud‐starter‐netflix‐eureka‐client

2、配置application.yml:

eureka:

client:

registerWithEureka:true#服务注册开关

fetchRegistry:true#服务发现开关

serviceUrl:#Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔

defaultZone:${EUREKA_SERVER:}

instance:

prefer‐ip‐address:true#将自己的ip地址注册到Eureka服务中

ip‐address:${IP_ADDRESS:127.0.0.1}

instance‐id:${spring.application.name}:${server.port}#指定实例id

3、启动类上加注解@EnableDiscoveryClient ,表示它是一个Eureka的客户端

4、刷新Eureka Server查看注册情况

同理可将需要注册的服务注册到Eureka Server。

2、Feign远程调用

服务层被拆分成了很多的微服务,服务与服务之间难免发生交互调用,这时候就需要用到远程调用,接下来带大家入门及使用

2.1Ribbon

1、简介

Ribbon是Netflix公司开源的一个负载均衡的项目(),它是一个基于HTTP、TCP的客户端负载均衡器,通过负载均衡来实现系统的高可用、集群扩容等功能。

如下图是服务端负载均衡架构图:

用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。 

客户端负载均衡架构图:

客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均衡服务。

 2、测试Ribbon

Spring Cloud引入Ribbon配合 restTemplate 实现客户端负载均衡。Java中远程调用的技术有很多,如:webservice、socket、rmi、Apache HttpClient、OkHttp等,互联网项目使用基于http的客户端较多,下面介绍使用的是OkHttp。

首先加入Maven依赖:

!--如果依赖了spring-cloud-starter-eureka,会自动添加spring-cloud-starter-ribbon依赖--

org.springframework.cloud

spring‐cloud‐starter‐ribbon

com.squareup.okhttp3

okhttp

在application.yml中配置Ribbon参数:

ribbon:

MaxAutoRetries:2#最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试

MaxAutoRetriesNextServer:3#切换实例的重试次数

OkToRetryOnAllOperations:false#对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false

ConnectTimeout:5000#请求连接的超时时间

ReadTimeout:6000#请求处理的超时时间

负载均衡测试:

启动两个cms服务,端口要不一致

定义RestTemplate,使用@LoadBalanced注解:

@Bean

@LoadBalanced

publicRestTemplaterestTemplate(){

returnnewRestTemplate(newOkHttp3ClientHttpRequestFactory());

}

远程调用cms的查询页面接口:

//负载均衡调用

@Test

publicvoidtestRibbon(){

//服务id

String serviceId ="XC‐SERVICE‐MANAGE‐CMS";

for(inti=0;i10;i++){

//通过服务id调用

ResponseEntity forEntity = restTemplate.getForEntity("http://"+ serviceId

+"/cms/page/get/5a754adf6abb500ad05688d9", CmsPage.class);

        CmsPage cmsPage = forEntity.getBody();

        System.out.println(cmsPage);

    }

}

添加@LoadBalanced注解后,restTemplate会走LoadBalancerInterceptor拦截器,此拦截器中会通过RibbonLoadBalancerClient查询服务地址,打断点观察每次调用的服务地址和端口,可以看到两个cms服务会轮流被调用。

2.2Feign

简介:

Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。

使用: 

添加Maven依赖:

dependency

    groupIdorg.springframework.cloud/groupId

    artifactIdspring‐cloud‐starter‐openfeign/artifactId

/dependency

dependency

    groupIdcom.netflix.feign/groupId

    artifactIdfeign‐okhttp/artifactId

/dependency

定义FeignClient接口:

@FeignClient(value = "XC_SERVICE_MANAGE_CMS")

publicinterfaceCmsPageClient{

//微服务接口路径

@GetMapping("/cms/page/get/{id}")

publicCmsPagefindById(@PathVariable("id")String id);

}

启动类添加@EnableFeignClients注解

测试:

@RunWith(SpringRunner.class)

@SpringBootTest

publicclassFeignTest{

@Autowired

CmsPageClient cmsPageClient;//接口代理对象,由Feign生成代理对象

@Test

publicvoidtestFeign(){

//发起远程调用

CmsPage cmsPage = cmsPageClient.findById("5a754adf6abb500ad05688d9");

        System.out.println(cmsPage);

    }

}

Feign工作原理:

1、 启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理对象

2、 @FeignClient(value = XcServiceList.XC_SERVICE_MANAGE_CMS)即指定了cms的服务名称,Feign会从注册中心获取cms服务列表,并通过负载均衡算法进行服务调用。

3、在接口方法 中使用注解@GetMapping("/cms/page/get/{id}"),指定调用的url,Feign将根据url进行远程调用。

SpringCloud集成Security安全(Eureka注册中心)

为了保护注册中心的服务安全,

避免恶意服务注册到Eureka,

需要对Eureka Server进行安全保护,

本文基于Spring Security方案,

为Eureka Server增加最简单的Basic安全认证。

修改pom.xml,添加spring-boot-starter-security依赖:

修改application.yml,配置磨圆用磨冲户名密码:

先只启动Eureka Server,

通过浏览器的URL访问注册中心,

首先会跳到登录界面,

要求输入用户名密码:

认证成功后,访问到管理界面:

Security默认启用了csrf检验,

CSRF一般指跨站请求伪造攻击,

要在Eureka Server端配置关闭csrf检验,

否则Eureka Client无法访问注册中心,

新建类WebSecurityConfig.java如下:

客户端要访问配置中心,

需要修改application.yml,

配置上面的用户名密码:

目前配置文件支持如下格式配置用户名密码:

HTTP基本身份认证将自动添加到Eureka Client。

对于更复杂的需瞎游歼求,

可以创建类型为DiscoveryClientOptionalArgs的@Bean,

并将ClientFilter实例注入其中。

注意由于Eureka的限制,

不可能支持每台服务器的基本身份认证凭证,

因此集群时只使用找到的第一组身份认证凭证。

Spring cloud eureka 安全认证基本配置

1.3. Authenticating with the Eureka Server

SpringCloud创建Eureka模块

本文详细介绍Spring Cloud创建Eureka模块的方法,

基于已经创建好的Spring Cloud父工程,

请参考 SpringCloud创建项目父工程 ,

在里面创建Eureka模块,

用于Spring Cloud的微服务注册。

这里介绍的是Eureka单机版。

这一步创建一个Maven Module,

作为Spring Cloud的父工程下的一个子工程:

在父工程spring-cloud-demo上右键 - New - Other... - Maven - Maven Module

勾选Create a simple project(skip archetype selection),

输入Module Name:eureka-server,

查看Parent Project:spring-cloud-demo,

如果不是自己选择的父工程,请重新选择。

点击Finish完成工程创建。

创建后可以看到pom.xml如下:

在pom.xml中增加eureka-server的依赖:

在src/main/resource目录下新增application.yml文件,

并且增加如下配置:

在src/main/java目录下新增主启动类,

Package:com.yuwen.spring.eureka

Name:EurekaServerApplication

然后修改EurekaServerApplication.java如下,

注意一定要有@EnableEurekaServer注解,

表示这是一个Eureka服务注册中心:

右键主启动类EurekaServerApplication.java,

Run As ... - Java Application

成功启动日志如下,

可以看到对外提供的服务端口是7001:

在前配浏览器中访问Eureka服务页面:慧乱指

可以看到如下页面:

Eureka服务启动后陪尺,

客户端可以注册到Eureka,

在pom.xml中增加eureka-client的依赖:

在application.yml中配置自己的主机名,

以及连接的eureka地址:

然后在客户端的主启动类上面加@EnableEurekaClient注解,

这样客户端服务启动之后,

可以看到Eureka页面已经有客户端注册了:

关于springcloudeureka和springcloudeureka原理的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签列表