文章目录
🍃前言
在我们前面进行搭建微服务,在进行远程调用时进行远程调用的时候,我们发现我们的远程调用url是写死的。
string url = "http://127.0.0.1:9090/product/"+ orderinfo.getproductid();
当更换机器,或者新增机器时,这个url就需要跟着变更,就需要去通知所有的相关服务去修改。随之⽽来的就是各个项⽬的配置⽂件反复更新,各个项⽬的频繁部署。这种没有具体意义,但⼜不得不做的⼯作,会让⼈⾮常痛苦
🎍解决方案
试想⽣活中的场景
机构电话如果发⽣变化,通知114。⽤⼾需要联系机构时,先打114查询电话,然后再联系各个机构
114查号台的作⽤主要有两个:
- 号码注册:服务⽅把电话上报给114
- 号码查询:使⽤⽅通过114可以查到对应的号码
同样的,微服务开发时,也可以采⽤类似的⽅案。
-
服务启动/变更时,向注册中⼼报道。注册中⼼记录应⽤和ip的关系。
-
调⽤⽅调⽤时,先去注册中⼼获取服务⽅的ip,再去服务⽅进⾏调⽤
🚩关于注册中⼼
在最初的架构体系中,集群的概念还不那么流⾏,且机器数量也⽐较少,此时直接使⽤dns+nginx就可以满⾜⼏乎所有服务的发现。相关的注册信息直接配置在nginx。但是随着微服务的流⾏与流量的激增,
机器规模逐渐变⼤,并且机器会有频繁的上下线⾏为,这种时候需要运维⼿动地去维护这个配置信息是⼀个很⿇烦的操作。
所以开发者们开始希望有这么⼀个东西,它能维护⼀个服务列表,哪个机器上线了,哪个机器宕机了,这些信息都会⾃动更新到服务列表上,客⼾端拿到这个列表,直接进⾏服务调⽤即可。这个就是注册中⼼
注册中⼼主要有三种⻆⾊:
- 服务提供者(server):⼀次业务中, 被其它微服务调⽤的服务, 也就是提供接给其它微服务
- 服务消费者(client):⼀次业务中, 调⽤其它微服务的服务. 也就是调⽤其它微服务提供的接
- 服务注册中⼼(registry): ⽤于保存server 的注册信息, 当server 节点发⽣变更时,registry会同步变更. 服务与注册中⼼使⽤⼀定机制通信, 如果注册中⼼与某服务⻓时间⽆法通信, 就会注销该实例.
他们之间的关系以及⼯作内容, 可以通过两个概念来描述:
- 服务注册:服务提供者在启动时, 向 registry 注册⾃⾝服务, 并向 registry 定期发送⼼跳汇报存活状
态. - 服务发现: 服务消费者从注册中⼼查询服务提供者的地址,并通过该地址调⽤服务提供者的接⼝. 服务
发现的⼀个重要作⽤就是提供给服务消费者⼀个可⽤的服务列表
🚩cap理论
谈到注册中⼼,就避不开cap理论。
cap 理论是分布式系统设计中最基础,也是最为关键的理论,理论大致如下:
- ⼀致性(consistency) cap理论中的⼀致性, 指的是强⼀致性。所有节点在同⼀时间具有相同的数据
- 可⽤性(availability) 保证每个请求都有响应(响应结果可能不对)
- 分区容错性(partition tolerance) 当出现⽹络分区后,系统仍然能够对外提供服务
cap 理论告诉我们: ⼀个分布式系统不可能同时满⾜数据⼀致性, 服务可⽤性和分区容错性这三个基本
需求, 最多只能同时满⾜其中的两个.
在分布式系统中, 系统间的⽹络不能100%保证健康, 服务⼜必须对外保证服务. 因此partition tolerance是不可避免. 那就只能在c和a中选择⼀个. 也就是cp或者ap架构
两个架构的区别在于:
- cp架构: 为了保证分布式系统对外的数据⼀致性, 于是选择不返回任何数据
- ap架构: 为了保证分布式系统的可⽤性, 节点2返回v0版本的数据(即使这个数据不正确)
🚩常见的注册中心
- zookeeper
- eureka
- nacos
三者所选择的 cap 理论也不一样
zookeeper | eureka | nacos | |
---|---|---|---|
cap理论 | cp | ap | cp或ap,默认ap |
本次博主主要介绍 eureka 的使用
🎄eureka
eureka是netflix oss套件中关于服务注册和发现的解决⽅案
eureka主要分为两个部分:
- eureka server: 作为注册中⼼server端, 向微服务应⽤程序提供服务注册, 发现, 健康检查等能⼒
- eureka client: 服务提供者, 服务启动时, 会向eureka server 注册⾃⼰的信息(ip,端⼝,服务信息等),eureka server 会存储这些信息
注意,以下的演示是基于【spring cloud】微服务的简单搭建 的基础进行搭建的。不了解的小伙伴可以先去看一下博主所写的微服务的简单搭建。
关于eureka的使用, 主要包含以下三个部分:
- 搭建eureka server
- 将order-service, product-service 都注册到eureka
- order-service远程调⽤时, 从eureka中获取product-service的服务列表, 然后进⾏交互
🚩搭建 eureka server
eureka-server 是⼀个独⽴的微服务
🎈创建eureka-server ⼦模块
🎈引入依赖
依赖如下:
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-server</artifactid>
</dependency>
🎈项目构建插件
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
🎈书写启动类
代码如下:
@enableeurekaserver
@springbootapplication
public class eurekaapplication {
public static void main(string[] args) {
springapplication.run(eurekaapplication.class,args);
}
}
🎈编写配置文件
配置如下:
server:
port: 10010
spring:
application:
name: eureka-serve
eureka:
instance:
hostname: localhost
client:
fetch-registry: false # 表⽰是否从eureka server获取注册信息,默认为true.因为这是⼀个单点的eureka server,不需要同步其他的eureka server节点的数据,这⾥设置为false
register-with-eureka: false # 表⽰是否将⾃⼰注册到eureka server,默认为true.由于当前应⽤就是eureka server,故⽽设置为false.
service-url:
# 设置与eureka server的地址,查询服务和注册服务都需要依赖这个地址.
defaultzone: http://${eureka.instance.hostname}:${server.port}/eureka/
🎈启动验证服务
启动服务, 访问注册中⼼: http://127.0.0.1:10010/
出现以下界面说明启动成功了
🌳服务注册
接下来我们把product-service 注册到eureka-server中
🚩引⼊eureka-client依赖
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
</dependency>
🚩完善配置文件
添加服务名称和eureka地址
spring:
application:
name: product-service
eureka:
client:
service-url:
defaultzone: http://127.0.0.1:10010/eureka
🚩启动服务
刷新我们的注册中心,就可以看到以下场景
可以看到product-service已经注册到 eureka上了
🎄服务发现
接下来我们修改order-service, 在远程调⽤时, 从eureka-server拉取product-service的服务信息, 实现
服务发现
🚩引入依赖
服务注册和服务发现都封装在eureka-client依赖中, 所以服务发现时, 也是引⼊eureka-client依赖
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
</dependency>
🚩完善配置文件
服务发现也需要知道eureka地址,因此配置内容依然与服务注册⼀致,都是配置eureka信息
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultzone: http://127.0.0.1:10010/eureka
🚩远程调用
远程调⽤时,我们需要从eureka-server中获取product-service的列表(可能存在多个服务),并选择其中
⼀个进⾏调⽤
@slf4j
@service
public class orderservice {
@autowired
private ordermapper ordermapper;
@autowired
private resttemplate resttemplate;
@resource
private discoveryclient discoveryclient;
public orderinfo selectall(integer userid) {
orderinfo orderinfo = ordermapper.selectall(userid);
//string url = "http://127.0.0.1:9999/product/" + orderinfo.getproductid();
list<serviceinstance> instances = discoveryclient.getinstances("product-service");
//服务可能有多个, 获取第⼀个
system.out.println("instances" + instances.size());
eurekaserviceinstance instance = (eurekaserviceinstance)instances.get(0);
log.info(instance.getinstanceid());
//拼接url
string url = instance.geturi()+"/product/"+ orderinfo.getproductid();
productinfo productinfo = resttemplate.getforobject(url, productinfo.class);
orderinfo.setproductinfo(productinfo);
return orderinfo;
}
}
🚩启动服务
刷新注册中心。我们可以看到order-service已经注册到eureka上了
访问order-service的相应接口,我们也可以看到调用成功。
⭕总结
关于《【spring cloud】 使用eureka实现服务注册与服务发现》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!
发表评论