Eureka服务注册与发现
什么是服务注册与发现
Eureka采用了cs得设计架构,eureka server 作为服务注册功能得服务器,它式服务注册得中心,而系统中得其他微服务,使用eureka得客户端连接到eureka server并维持心跳连接,这样就可以通过eureka server来监控系统中各个微服务是否正常运行
在服务注册与发现中,有一个注册中心。当服务器启动得时候,会把当前自己服务器得信息比如 服务器地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地rpc调用rpc远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理),在任何的rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
eureka server端服务注册中心配置
-
改pom
<!--eureka服务端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!--父工程已经导入了spring-cloud的版本锁定 所以此处不再写版本-->
-
改yml
spring: application: name: server server: port: 10086 eureka: instance: hostname: localhost #eureka服务端的实例名称 client: service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka register-with-eureka: false #false表示不向注册中心注册自己 fetch-registry: false #false表示我自己这段就是服务端,我的职责是维护实例,并不需要去检索服务
-
修改主启动
@SpringBootApplication //eureka有服务端和客户端 要声明我这里是服务端 同时注册中心服务端不需要写任何的业务代码 @EnableEurekaServer public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
eureka client的配置
order注册进eureka作为服务提供者
-
改pom
<!-- 导入eureka的客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
-
改yaml
server: port: 8081 spring: datasource: url: jdbc:mysql://192.168.200.128:3306/cloud_user?useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver application: name: userservice #声明自己服务的名字 就是入住进eureka服务器的服务的名称 注意不要使用短横线和下划线 mybatis: type-aliases-package: cn.itcast.user.pojo configuration: map-underscore-to-camel-case: true logging: level: cn.itcast: debug pattern: dateformat: MM-dd HH:mm:ss:SSS eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka register-with-eureka: true #是否将自己注册进eurekaserver 默认为true fetch-registry: true #是否从eurekaserver抓取已经有的注册的信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
-
改主启动
@SpringBootApplication
@EnableEurekaClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
order注册进eureka作为服务消费者
pom导入的依赖同上
yaml中需要修改spring.application.name=orderservice
eureka集群原理说明
eureka server
服务注册:将服务信息注册进注册中心
服务发现:从注册中心获取服务信息
实质:存key服务取value调用地址
- 先启动eureka注册中心
- 启动服务提供者userservice
- userservice启动后会把自身信息(比如服务地址以别名方式注册进eureka)
- 消费者order服务再需要调用接口时,使用服务别名去注册中心获取实际的rpc远程调用地址
- 消费者获得调用地址后底层实际上是利用httpclient技术实现远程调用
- 消费者获得服务地址后会缓存在本地jvm中,默认每间隔30秒更新一次服务调用地址
问题:微服务rpc远程服务调用最核心的是什么?
高可用,如果注册中心只有一个,出故障了,会导致整个微服务环境不可用,所以要搭建eureka注册中心集群,实现负载均衡+故障容错
集群筹建步骤
总体就是eureka server相互注册 互相守望
服务端两个eureka server 相互注册
eureka server 因为是一台所以对名字了更改
hosts添加如下
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
两个server的配置文件如下
spring:
application:
name: server
server:
port: 10086
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
service-url:
defaultZone: http://eureka7002.com:10087/eureka
register-with-eureka: false #false表示不向注册中心注册自己
fetch-registry: false #false表示我自己这段就是服务端,我的职责是维护实例,并不需要去检索服务
spring:
application:
name: server
server:
port: 10087
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
service-url:
defaultZone: http://eureka7001.com:10086/eureka
register-with-eureka: false #false表示不向注册中心注册自己
fetch-registry: false #false表示我自己这段就是服务端,我的职责是维护实例,并不需要去检索服务
接下来在对消费者进行注册的配置
server:
port: 8082
spring:
datasource:
url: jdbc:mysql://192.168.200.128:3306/cloud_order?useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
application:
name: orderservice
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
eureka:
client:
service-url:
defaultZone: http://eureka7002.com:10087/eureka,http://eureka7001.com:10086/eureka
消费者集群的搭建
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>
主机名称:服务名称的修改
访问信息有ip信息提示
eureka:
client:
service-url:
defaultZone: http://eureka7002.com:10087/eureka,http://eureka7001.com:10086/eureka
register-with-eureka: true #是否将自己注册进eurekaserver 默认为true
fetch-registry: true #是否从eurekaserver抓取已经有的注册的信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
instance:
instance-id: payment8081 #修改显示主机名
prefer-ip-address: true #访问信息有ip显示
服务发现Discovery
对于注册进eureka里边的微服务,可以通过服务发现来获得该服务的信息
注意自动装配时discoveryClient的倒包
import org.springframework.cloud.client.discovery.DiscoveryClient;
-
得到服务清单列表List services = discoveryClient.getServices();
List<ServiceInstance> userservice = discoveryClient.getInstances("userservice"); for (ServiceInstance serviceInstance : userservice) { String host = serviceInstance.getHost(); String instanceId = serviceInstance.getInstanceId(); int port = serviceInstance.getPort(); URI uri = serviceInstance.getUri(); System.err.println(host);//169.254.44.164 System.err.println(instanceId);//payment8081 System.err.println(port);//8081 System.err.println(uri);//http://169.254.44.164:8081 }
-
根据服务名称获取服务实例List userservice = discoveryClient.getInstances(“userservice”);
Eureka自我保护
某时刻一个微服务不可用了,eureka不会立即清理,依旧会对该微服务的信息进行保存
属于cap的ap 高可用和分区容错性
为什么产生eureka自我保护机制?
为了防止eurekaclient可以正常运行,但是与eurekaserver网络不通的情况下,eurekaserver不会立即将eurekaclient服务剔除
什么是自我保护模式?
默认情况下,如果eurekaserver在一定时间内没有接收到某个微服务实例的心跳,eurekaserver将会注销实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤时),微服务与eurekaserver之间无法正常通讯,以上行为就会变的非常危险了-因为微服务本身是健康的,此时不应该注销这个微服务,eureka通过自我保护来解决这个问题-当eurekaserver节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式
在自我保护模式中,eurekaserver会保护服务注册表中的信息,不再注销任何服务实例
就是宁可保留错误的服务注册信息,也不要盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着
综上:自我保护是一种应对网络异常的安全保护策略。宁可同时保留所有微服务(健康的和不健康的)也不会盲目注销任何健康的微服务。使用自我保护模式,可以让eureka集群更加健壮稳定
怎么禁止自我保护
eureka:
server:
enable-self-preservation: false 可以禁止自我保护