分布式框架容易遇到的问题:
- 服务器ip可能会更换,如果后台使用硬编码写死ip将不利于代码的维护
- 如果服务器ip更换了,消费方服务器得不到及时的通知及修改,将会无法访问生产者服务器
- 如果生产者服务器宕机,消费者服务器无法得到有效的恢复,可能会造成服务雪崩
- 无法实现负载均衡
springcloud:微服务架构
常见组件:
- eureka注册中心
- GateWay服务网关
- Ribbon负载均衡
- Feign服务调用
- Hystrix熔断器
Eureka注册中心
-
注册
生产者将自己的服务器地址注册到Eureka进行统一管理 -
发现
eureka将符合条件的服务器地址发送给消费者,以便消费者进行调用 -
心跳
eureka和生产者之间通过心跳
机制进行检测,如果有生产者服务器出现宕机,eureka会自动将其地址剔除 -
Eureka的三个核心角色
服务注册中心、服务提供者/生产者、服务消费者
创建Eureka Server注意事项:
- Eureka pom文件:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 在启动类添加注解:
@EnableEurekaServer
声明当前应用是Eureka服务 - yml文件设置Eureka地址
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:12130/eureka
Eureka功能图片概述
注意: SpringCloud的版本对springboot版本有限制,需要去springcloud官网查看支持的springboot版本. 参考文件:springcloud项目版本冲突
创建Eureka生产者服务
- pom依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 启动类添加注解:
@EnableDiscoveryClient
开启Eureka客户端发现功能 - yml文件添加配置:
设置Eureka应用地址:
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:12130/eureka
设置生产者服务器名称:spring: application: name: user-service
创建Eureka消费者服务
-
同创建生产者服务
-
调用服务:
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
public User findById(@PathVariable Long id) {
ServiceInstance instance = discoveryClient.getInstances("user-service").get(0);
return restTemplate.getForObject("http://" + instance.getHost() + ":" + instance.getPort() + "/user/findUser/" + id, User.class);
}
配置多台Eureka Server
- 多个Eureka Server之间也可以相互注册,当生产者注册到某个Eureka Server集群节点时,该节点会把生产者的信息同步给集群的所有节点,从而实现数据同步.例:有a,b,c三个Eureka Server为一个集群,
此时需要:a注册到b ,c b注册到a , c c注册到a,b - 配置信息:
server:
port: ${port:1213} # ${port:1213} 如果port有值则使用port的值,否则使用1213
spring:
application:
name: eureka-server
eureka:
client:
service-url:
defaultZone: ${defaultZone:http://127.0.0.1:1213/eureka}
在启动项的环境配置Environment里添加:-Dport=1213 -DdefaultZone=http://127.0.0.1:1214/eureka
Eureka客户端与服务端配置
服务端/生产者
服务端需要向Eureka Server进行注册,并完成服务续约等工作
服务注册
- 生产者在启动时,会检查`eureka.client.register-with-eureka是否为true,为true则会向Eureka Server发送一个Rest请求,请求中携带有自己的元数据,EurekaServer会将元数据记录到一个双层Map中
双层Map:
- 第一层Map的key为服务名称,一般是Spring.application.name的值.
- 第二层Map的key为服务的实例Id,一般是Host+ServiceId+port 如:127.0.0.1:user-servuce:1213
- 值则是服务的实例对象
eureka:
client:
service-url:
#defaultZone: http://127.0.0.1:1213/eureka,http://127.0.0.1:1214/eureka
defaultZone: http://127.0.0.1:1213/eureka
instance:
prefer-ip-address: true #消费者获取生产者host时优先使用ip地址
ip-address: 127.0.0.1 #设置ip
服务续约
生产者会定时向EurekaServer发送一个Rest请求,告诉EurekaServer'我还活着',这个动作称为 renew
eureka:
instance:
lease-renewal-interval-in-seconds: 30 # 服务续约的间隔,每30s发送一次Rest请求
lease-expiration-duration-in-seconds: 90 #超过90s没有向EurekaServer发送请求,则认为此服务宕机
服务消费者
服务拉取
消费者启动时会检测eureka.client.fetch-registry
是否为true,如果为true则从EurekaServer定期拉取服务地址列表保存到本地
可以通过配置设置拉取服务地址列表的间隔
eureka:
client:
registry-fetch-interval-seconds: 30 #30s拉取一次服务地址
服务下线
当服务正常关闭时,会向EurekaServer发送一个下线的Rest请求,EurekaServer接收到后会将此服务视为下线状态
失效剔除
EurekaServer服务注册中心在启动时会创建一个定时任务,基于生产者的服务续约功能,每隔60s(默认60s)将90s(默认90s)内没有进行服务续约的服务进行剔除.
可以通过配置eureka.server.eviction-interval-timer-in-ms
配置失效剔除时间间隔,单位为毫秒
自我保护
EurekaServer有一个自我保护机制,如果15分钟内有超过85%的服务没有进行心跳续约,EurekaServer就会进入自动保护模式,在这个模式中不会剔除任何服务,直到网络故障恢复自动退出自我保护模式.这样有效避免了因为网络延迟造成的服务续约失败的问题.
可通过配置eureka.server.enable-self-preservation: true
开启或关闭自我保护模式(默认开启)