Spring Cloud-Eureka实现服务的注册与发现(二)
在Spring Cloud中是使用Eureka来实现服务的注册与发现的
请勿使用eureka2.x 用于生产 2.x已经停止开发了 使用1.x 最新版是1.9 我这里demo是使用1.9 详情:https://github.com/Netflix/eureka/wiki
项目骨架搭建
创建父工程
1.创建一个父工程 实现版本的统一管理 以及子项目的管理


然后下一步下一步
创建子工程



在对应的tab 勾选web和EurekaServer 创建项目后会自动生成pom依赖 注意右上角cloud版本
将eureka子工程的paren 节点改为指向父工程 这的各个节点需要改为 你的对应父工程的节点描述
<parent>
<groupId>com.liqiang</groupId>
<artifactId>spring-cloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
将工程的在父工程创建节点 并删除子工程的 没有的话就不管
<!--版本号的统一管理。 子类项目没有配置版本号的时候 会从子往上找 找到 dependencyManagement 找到对应的版本-->
<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>
父工程model配置上eureka子工程
<modules>
<module>spring-cloud-eureka</module>
</modules>

最后将父工程的Src目录删除 这样我们项目的基础骨架就搭建好了 可以进行eureka的相关配置了
个人习惯 喜欢用yml配置 所以讲resource下面的application.properties 后缀改为yml

最后将parent pom文件的<packaging>jar</packaging> 改为<packaging>pom</packaging>
然后执行parent安装
配置Eureka服务端
1.增加pom依赖并在Application类添加@EnableEurekaServer注解 开启服务注册功能
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaServer //开启服务注册的功能
public class SpringCloudEurekaApplication { public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaApplication.class, args);
}
}
2.配置application.yml
server:
port: 1111 eureka:
instance:
hostname: localhost #主机名
client:
registerWithEureka: false #不注册自己 只维护服务 #集群情况下 是需要改成true 的因为 集群是注册中心 相互注册自己 同步服务
fetchRegistry: false #是否开启从 Eureka-Server 获取注册信息。默认值:true 集群情况下需要为true的 因为 会在别的注册中心 获取服务
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #集群情况配置多注册中心,号隔开 单机情况下 不配置也没关系
3.访问http://127.0.0.1:1111

表示注册中心搭建成功。。registerWithEureka 我们设置了false 表示不注册 自己 我们可以尝试改成true 则可以看到 服务里面会出现服务
配置服务提供者
1.跟创建注册中心一样 创建一个名为provider的项目 pom配置文件 跟provider一致
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

2.配置 application.yml配置文件
spring:
application:
name: provider #服务名字
server:
port: 8081
eureka:
instance:
hostname: localhost #当前实例的主机名字
client:
serviceUrl:
defaultZone: http://127.0.0.1:1111/eureka/ #注册中心地址
3. @EnableDiscoveryClient 开启服务注册到注册中心的功能
@SpringBootApplication
@EnableDiscoveryClient //开启将服务注册到注册中心
public class SpringCloudProviderApplication { public static void main(String[] args) {
SpringApplication.run(SpringCloudProviderApplication.class, args);
}
}
4.创建对一个对外暴露的服务(注意 必须在application启动类所在目录或者下级目录)
@RestController
public class HelloServerContorrler {
@RequestMapping(value = "/hello")
public String hello(){
return "hello";
}
}
5.启动eureka 再启动provider 可以发现服务已经注册到注册中心

服务消费者配置
跟上面一样创建一个consumer

pom配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--从注册中心获取服务的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--rabbon客户端的负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
启动类配置
@SpringBootApplication
@EnableDiscoveryClient //开启服务发现
public class ConsumerApplication { public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
//LoadBalanced 通过代理RestTemplate 实现客户端负载均衡的能力
@LoadBalanced
@Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
}
yml配置
spring:
application:
name: consumer
server:
port: 9001
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:1111/eureka #注册中心地址
调用服务
@Controller
public class HelloContorller {
//applicaton启动类配置的@LoadBalanced 的代理对象
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/hello")
@ResponseBody
public String hell(){
//PROVIDER需要大写 这里没有配置物理地址 而是服务名 是去服务集群 获得集群服务地址 来实现负载均衡
return restTemplate.getForEntity("http://PROVIDER/hello",String.class).getBody();
}
}
访问http://127.0.0.1:9001/hello

注册中心集群
1.配置host文件 模拟域名映射ip 比如我们通过http://peer1:8081/user 访问 实际上是访问peer1对应的ip 如http://127.0.0.1:8081/user
host文件在哪儿自行百度
127.0.0.1 peer1
127.0.0.1 peer2

2.copy2个配置文件 端口改为不一致

配置文件1
server:
port: 1111
eureka:
instance:
hostname: localhost #主机名
client:
registerWithEureka: true #将自己注册到 集群中的其他注册中心
fetchRegistry: true #从注册中心同步服务。
serviceUrl:
defaultZone: http://peer1:1112/eureka/ #集群汇总的其他注册中心地址 多个,号隔开
spring:
application:
name: eureka
配置文件2
server:
port: 1112
eureka:
instance:
hostname: localhost #主机名
client:
registerWithEureka: true #将自己注册到 集群中的其他注册中心
fetchRegistry: true #从注册中心同步服务。
serviceUrl:
defaultZone: http://peer1:1111/eureka/ #集群汇总的其他注册中心地址 多个,号隔开
spring:
application:
name: eureka
注册中心集群 是根据注册中心之间相互注册和相互订阅同步服务实现的 可以通过上面配置看出来
4.provider和cusumer的注册中心地址指向集群的注册中心所有
spring:
application:
name: consumer
server:
port: 9001 eureka:
client:
serviceUrl:
defaultZone: http://peer1:1111/eureka,http://peer2:1112/eureka
spring:
application:
name: provider #服务名字
server:
port: 8081
eureka:
instance:
hostname: localhost #当前实例的主机名字
client:
serviceUrl:
defaultZone: http://peer1:1111/eureka,http://peer2:1112/eureka #注册中心地址
3.打包安装 手动执行jar包 并分别指定配置文件路径替换成本地打包的路径
java -jar /Users/liqiang/Desktop/java开发环境/javadom/spring-cloud-parent/spring-cloud-eureka/target/spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar /Users/liqiang/Desktop/java开发环境/javadom/spring-cloud-parent/spring-cloud-eureka/target/spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
5.启动provider
6.启动cusumer

高可用集群的注册中心就搭建好了
eureka逻辑图

默认服务提供者启动会注册服务到注册中心的双层map 第一层key为服务名 第二层为key为实例信息 同时维持一个心跳方式注册中心认为自己挂了将自己从服务列表剔除
不知道怎么测试 正常关闭的话会通过REST通知到服务注册中心 注册中心将服务状态改为down 再通知下去
客户端配置:
# 多久未收到心跳,剔除instance 要比心跳时间大
eureka.instance.lease-expiration-duration-in-seconds:30
# 心跳时间间隔
eureka.instance.lease-renewal-interval-in-seconds: 5
服务端配置:
eureka.instance.eviction-interval-timer-in-ms: 5000 多久去剔除一次指定时间没有续约的服务
消费者启动会拉取注册中心服务。为了性能 eurekaServer会维护30秒的服务清单 该清单默认30秒更新一次 可以通过以下配置
eureka.client.registry-fetch-interval-seconds=30 确保开启 eureka.client.fetchRegistry: false #是否开启从 Eureka-Server 获取注册信息。默认值:true
服务保护机制

前面说了 注册中心是通过 服务提供者维护的心跳来控制服务是否有效 当15分钟内 心跳失败的比例在85%会开启保护机制 这个时候服务就不会因为续约过期而下线(个人觉得是为了防止 注册中心 网络出现问题 导致服务提供者通过心跳请求不能成功续约) 保护机制会导致客户端拿到 无效的服务 所以需要客户端启用启用重试和断路器机制
可以通过eureka.instance.enable-self-preservation=false 关闭保护机制(不建议开启 本地开发可以开启)
Eureka初始化过程
1.配置信息启动都会封装到EurekaClientConfig
2.com.netflix.discovery.DiscoveryClient 根据EurekaClientConfig会初始化3个定时任务 分别服务注册 服务获取 服务续约(心跳) 三个定时任务都是根据rest接口而来的
通过源码
com.netflix.discovery.DiscoveryClient的构造函数可以发现初始化定时任务的方法
private void initScheduledTasks() {
//是否从注册中心订阅服务对应eureka.client.registerWithEureka配置
if (clientConfig.shouldFetchRegistry()) {
//多久去注册中心拉取一次服务对应eureka.client.registry-fetch-interval-seconds
int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
//服务拉取失败的重试时间系数
int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
scheduler.schedule(
new TimedSupervisorTask(
"cacheRefresh",
scheduler,
cacheRefreshExecutor,
registryFetchIntervalSeconds,
TimeUnit.SECONDS,
expBackOffBound,
new DiscoveryClient.CacheRefreshThread()
),
registryFetchIntervalSeconds, TimeUnit.SECONDS);
}
//是否对注册中心注册服务 对应eureka.client.fetchRegistry
if (clientConfig.shouldRegisterWithEureka()) {
//心跳间隔时间 对应eureka.instance.lease-renewal-interval-in-seconds
int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
//心跳超时重试的系数对应
int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
logger.info("Starting heartbeat executor: " + "renew interval is: {}", renewalIntervalInSecs);
// Heartbeat timer
scheduler.schedule(
new TimedSupervisorTask(
"heartbeat",
scheduler,
heartbeatExecutor,
renewalIntervalInSecs,
TimeUnit.SECONDS,
expBackOffBound,
new DiscoveryClient.HeartbeatThread()
),
renewalIntervalInSecs, TimeUnit.SECONDS);
// 服务注册定时任务
instanceInfoReplicator = new InstanceInfoReplicator(
this,
instanceInfo,
clientConfig.getInstanceInfoReplicationIntervalSeconds(),
2); // burstSize
statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
@Override
public String getId() {
return "statusChangeListener";
}
@Override
public void notify(StatusChangeEvent statusChangeEvent) {
if (InstanceInfo.InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
InstanceInfo.InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
// log at warn level if DOWN was involved
logger.warn("Saw local status change event {}", statusChangeEvent);
} else {
logger.info("Saw local status change event {}", statusChangeEvent);
}
instanceInfoReplicator.onDemandUpdate();
}
};
if (clientConfig.shouldOnDemandUpdateStatusChange()) {
applicationInfoManager.registerStatusChangeListener(statusChangeListener);
}
instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
} else {
logger.info("Not registering with Eureka server per configuration");
}
}
配置参考
https://blog.csdn.net/cvntopuyef/article/details/78477724
Instance配置
服务注册会向注册中心发送一些用于描述自己的的元数据信息比如 服务名称、 实例名称、 实例IP、 实例端口等
在使用 Spring CloudEureka的时候, 所有的配置信息都通过org.springframework.cloud.netflix.eureka.EurekalnstianceConfigBean进行加载
但在真正进行服 务注册的时候, 还是会包装成com.netflix.appinfo.Instiancelnfo
可以通过eureka.instance.metadataMap.<key>=<value> 来进行自定发送数据
eureka.instance.instanceid 指定服务实例id 默认主机名+端口
指定服务info和heath端点路径 heath用于服务更新服务状态 down up info用于注册中心点击服务访问信息 保证这2类不要404 默认一般不用修改 当上下文修改 可以通过以下配置指定需要引入
spring-boot-starter-actuator模块
management.context-path=/hello
eureka.instance.statusPageUrlPath=${management.context-path}/info
eureka.instance.healthCheckUrlPath=${management.context-path}/health
instance其他配置

Spring Cloud-Eureka实现服务的注册与发现(二)的更多相关文章
- Spring Cloud Eureka 实现服务注册与发现
微服务 是一种架构模式,跟具体的语言实现无关,微服务架构将业务逻辑分散到了各个服务当中,服务间通过网络层进行通信共同协作:这样一个应用就可以划分为多个服务单独来维护发布.构建一个可靠微服务系统是需要具 ...
- 服务注册发现Eureka之一:Spring Cloud Eureka的服务注册与发现
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...
- Spring Cloud Eureka Server高可用注册服务中心的配置
前言 Eureka 作为一个云端负载均衡,本身是一个基于REST的服务,在 Spring Cloud 中用于发现和注册服务. 那么当成千上万个微服务注册到Eureka Server中的时候,Eurek ...
- Spring Cloud Eureka Server使用(注册中心)
一.Spring Cloud Eureka 基于Netflix Eureka做了二次封装 由两个组件组成 Eureka Server 注册中心, 供服务注册的服务器 Eureka Client 服务注 ...
- Spring Cloud(二):Spring Cloud Eureka Server高可用注册服务中心的配置
前言 Eureka 作为一个云端负载均衡,本身是一个基于REST的服务,在 Spring Cloud 中用于发现和注册服务. 那么当成千上万个微服务注册到Eureka Server中的时候,Eurek ...
- Spring Cloud 系列之 Alibaba Nacos 注册中心(二)
本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Alibaba Nacos 注册中心(一) 本篇文章讲解 Nacos 注册中心集群环境搭建. Nacos 集群环境搭建 ...
- Spring Cloud Eureka 之服务端自我注册
Eureka服务端实现了一种自我注册机制,涉及配置项: eureka.client.register-with-eureka spring.application.name Eureka Server ...
- Spring Cloud Eureka 5 (服务发现与消费-简单的robbin使用)
通过上述介绍,我们已经有了服务注册中心和服务提供者 下面我们来尝试构建一个服务的消费者 它要完成两个功能,发现服务和消费服务,其中发现服务由eureka客户端完成,消费服务由ribbon完成. rib ...
- 《深入理解Spring Cloud与微服务构建》学习笔记(二十)~配置中心Spring Cloud Config
本例重新创建项目,构建一个空的mavan工程. 一.Config Server 从本地读取配置文件 新建一个moudle config_server ,pom添加依赖 <dependency ...
随机推荐
- luogu2828 [HEOI2016/TJOI2016]排序
题目大意 给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:(0,l,r)表示将区间[l,r]的数字升序排序:(1,l,r)表示将区间[l,r]的数字降序排序.最后询问第q位 ...
- NSURLSession 和 NSURLConnection 的比较
一.NSURLConnection 1.iOS2.0出现,iOS9.0后废弃的网络请求发送方式 2.可以在初始化时确定发送同步还是异步的请求,并且可以选择执行队列. +(void)sendAsynch ...
- [SDOI2004]打鼹鼠
...... 心血来潮,手打abs 结果...BZOJ上CE,洛谷上WA... 把宏定义换成函数就过了 显然一个点可以走到另一个点,当且仅当两点鼹鼠出现时间$\leq$两点间距离的曼哈顿距离 显然是D ...
- A - Design Tutorial: Learn from Math(哥德巴赫猜想)
Problem description One way to create a task is to learn from math. You can generate some random mat ...
- MySQL学习笔记之右连接
MySQL的右连接 #右连接,以右表为基表 select course.stuid,course.stuname,sex,course,city from class1 right join cour ...
- 带"签名"的请求接口实现
废话少说,直接上代码(⊙﹏⊙) class Program { //签名证书 public static X509Certificate2 cerSigneCert; private static c ...
- Node.js文件系统Api总结
//公共引用 var fs = require('fs'), path = require('path'); 1.读取文件readFile函数 //readFile(filename,[options ...
- 搭建Hive所遇到的坑
##一.基本功能: 1.启动hive时报错 java.lang.ExceptionInInitializerError at java.lang.Class.forName0(Native Metho ...
- HTML基础知识总结(一)
概述 HTML是将内容和内容显示形式结合在一起的语言,它对于内容显示形式的控制,主要是通过标签(元素)的属性,由于它对“内容显示形式”存在着很多的弊端,所以之后就出现了CSS,CSS就相当 ...
- 【sqli-labs】 less20 POST - Cookie injections - Uagent field - Error based (POST型基于错误的cookie头部注入)
以admin admin成功登陆之后,保存并显示了cookies信息 如果不点击Delete Your Cookie!按钮,那么访问 http://localhost/sqli-labs-master ...