Spring Cloud 高可用注册中心 Eureka Server

Spring Cloud 高可用注册中心 Eureka Server

SpringBoot 版本2.1.4.RELEASE、Spring Cloud版本Greenwich.RELEASE

Eureka系统架构图

register-with-eureka、fetch-registry参数对应图中的Registry、Get操作
Eureka架构详解

Eureka Server和Eureka Client

1、 Eureka Server提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息(例如IP、端口、微服务名称等),Eureka Server会存储这些信息;
2、Eureka Client是一个Java客户端,用于简化与Eureka Server的交互;
3、 微服务启动后,会周期性(默认30秒)地向Eureka Server发送心跳以续约自己的“租期”;eureka.instance.lease-renewal-interval-in-seconds=30
4、 如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认60秒);eureka.server.eviction-interval-timer-in-ms=60000
5、默认情况下,Eureka Server同时也是Eureka Client。多个Eureka Server实例,互相之间通过增量复制的方式,来实现服务注册表中数据的同步。Eureka Server默认保证在90秒内,Eureka Server集群内的所有实例中的数据达到一致。
6、所有Eureka Server节点都是对等体(peer),没有主节点选举,不存在主从。
7、Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势,首先,微服务无需每次请求都查询Eureka Server,从而降低了Eureka Server的压力。其次,即使Eureka Server所有节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者并完成调用。

服务治理

服务治理相关接口可查看Netflix的github:

https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
高可用注册中心代码

1、maven依赖:

<!-- eureka server注册中心-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 配置安全机制、只有经过验证的服务才可以注册到服务中心 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

2、注册中心监听事件:
依赖包"org.springframework.cloud.netflix.eureka.server.event"中包含了所有注册中心的监听事件

@Component
public class EurekaStateListener {

	/**
	日志**/
    private final static Logger logger = LoggerFactory.getLogger(EurekaStateListener.class);

    @EventListener
    public void listen(EurekaInstanceCanceledEvent  event) {
        logger.info("服务{}已下线", event.getAppName());
        logger.info("server地址信息{}", event.getServerId());
    }

    @EventListener
    public void listen(EurekaInstanceRegisteredEvent event) {
        InstanceInfo instanceInfo = event.getInstanceInfo();
        logger.info("服务{}进行注册", instanceInfo.getAppName()+ instanceInfo.getHostName() +"  "+ instanceInfo.getIPAddr() +"  "+ instanceInfo.getPort());
    }

    @EventListener
    public void listen(EurekaInstanceRenewedEvent event) {
        logger.info("服务{}进行续约", event.getServerId() +"  "+ event.getAppName());
    }

    @EventListener
    public void listen(EurekaRegistryAvailableEvent event) {
        logger.info("注册中心启动,{}", System.currentTimeMillis());
    }

    @EventListener
    public void listen(EurekaServerStartedEvent event) {
        logger.info("注册中心服务端启动,{}", System.currentTimeMillis());
    }
}

3、注册中心启动文件:

@EnableEurekaServer
@SpringBootApplication
public class RegistryServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(RegistryServerApplication.class, args);
	}

	/**
	 * springboot2.x添加了csrf,会导致无法完成注册中心的自我注册,此处打开配置
	 */
	@EnableWebSecurity
	static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http.csrf().ignoringAntMatchers("/eureka/**");
			super.configure(http);
		}
	}
}

4、注册中心配置文件:
bootstrap-node1.properties

server.port=9000
spring.security.user.name=admin
spring.security.user.password=1111
eureka.server.node1=localhost:9000
eureka.server.node2=localhost:9001
eureka.client.service-url.defaultZone=http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.node1}/eureka/,http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.node2}/eureka/

eureka.instance.prefer-ip-address=tru
eureka.server.enable-self-preservation=false
spring.application.name=registry-server
eureka.instance.instance-id=${spring.application.name}:${server.port}
spring.security.user.roles=SUPERUSER
eureka.server.eviction-interval-timer-in-ms=1000
eureka.instance.metadata-map.user.name=admin
eureka.instance.metadata-map.user.password=1111

bootstrap-node2.properties

# -Dspring.profiles.active=node2
server.port=9001
spring.security.user.name=admin
spring.security.user.password=1111
eureka.server.node1=localhost:9000
eureka.server.node2=localhost:9001
eureka.client.service-url.defaultZone=http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.node1}/eureka/,http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.node2}/eureka/

eureka.instance.prefer-ip-address=true
eureka.server.enable-self-preservation=false
spring.application.name=registry-server
eureka.instance.instance-id=${spring.application.name}:${server.port}
spring.security.user.roles=SUPERUSER
eureka.server.eviction-interval-timer-in-ms=1000
eureka.instance.metadata-map.user.name=admin
eureka.instance.metadata-map.user.password=1111

配置文件说明:
1、属性“eureka.client.service-url.defaultZone”中的/eureka/是不能修改的,如:

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

2、如果访问注册中心考虑安全性,可将用户密码配置到“eureka.client.service-url.defaultZone”属性中,格式:

http://username:password@ip:port/eureka/

3、配置“eureka.client.service-url.defaultZone“,最好是配置所有的Eureka Server,多个之间逗号分隔(如上图bootstrap-node*.properties配置),也包括当前注册中心。也可以配置成一个其他的配置中心,但这样就无法做到高可用。如果只配置当前的配置中心,就需要设置一下两个参数

eureka.client.fetch-registry=false、eureka.client.register-with-eureka=false

否则程序启动会报错,但是并不影响程序使用。
4、应用名和实例id配置
4.1、应用名/服务名不能含有下划线_,但是可以含是中划线,配置中心(spring-cloud-config-server)源码中有一段代码如下图所示:
在这里插入图片描述
4.2、实例id配置成可以区分不同实例的形式,如ip:port的形式,或spring.application.name:port的形式,例如:
在这里插入图片描述
如果部署的两个注册中心实例id均为registry-server,这里的列表就会值展示一个。如果该服务是服务提供方,好像会影响负载均衡的调用。总之最好可以通过instanceId可以区分不同实例。

5、启动命令:
1、java -jar -Dspring.profiles.active=node1 registry-server.jar
2、java -jar -Dspring.profiles.active=node2 registry-server.jar

6、注册中心web访问:localhost:9000或localhost:9001均可访问
如下图所示:
在这里插入图片描述
在这里插入图片描述

参数配置说明:

1、eureka.client.registry-fetch-interval-seconds
表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
2、eureka.instance.lease-expiration-duration-in-seconds
leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。
默认为90秒
如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。
该值至少应该大于leaseRenewalIntervalInSeconds
3、eureka.instance.lease-renewal-interval-in-seconds
leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。
默认30秒
4、eureka.server.enable-self-preservation
是否开启自我保护模式,默认为true。
默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。
Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
5、eureka.server.eviction-interval-timer-in-ms
eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒

注册中心github地址

下一篇:Spring Cloud使用MySQL的高可用配置中心Config Server

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值