快速搭建一个eureka 注册中心步骤说明
eureka server端
pom.xml文件中加入eureka 服务所需要的配置
<!-- 添加eureka server依赖包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
application.properties文件
#由于该应用为注册中心,所以设置为false,表示不向注册中心注册自己
eureka.client.fetch-registry=false
#注册中心的职责是维护实例,并不需要去检索服务,所以设置为false
eureka.client.register-with-eureka=false
#服务注册中心地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.instance.hostname=127.0.0.1
server.port=8081
启动类:
必须加上@EnableEurekaServer 注解,表示启动一个服务注册中心提供给其他应用进行对话
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
eureka 客户端
pom.xml引入eureka 依赖包,需要注意的是,版本号必须与服务端一致
<!-- 添加eureka server依赖包 注册中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
application.properties文件
注意端口号必须与服务端的一致
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8081/eureka/
spring.application.name=hello-service
启动类
@EnableDiscoveryClient 注解,激活Eureka中的DiscoveryClient实现(服务自动注册到注册中心,创建DiscoverClient接口针对Eureka客户端的EurekaDiscoverClient实例)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceStart {
public static void main(String[] args) {
SpringApplication.run(ServiceStart.class, args);
}
}
Controller类
启动服务注册中心
启动出现如下信息,说明启动成功
浏览器访问:http://127.0.0.1:8081,会出现如下界面,这只是一个空的注册中心
启动eureka客户端
再次刷新服务注册中心,会发现hello-service已成功注册
下面来搭建高可用注册中心
在刚才的eureka服务端项目中新增,application-peer1.properties、application-peer2.properties两个配置文件,记住必须是新增,否则项目在打包编译时会报错:
application-peer1.properties
注册中心指向peer2
spring.application.name=eurekaServer
server.port=8081
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:8082/eureka/
application-peer2.properties
注册中心指向peer1
spring.application.name=eurekaServer
server.port=8082
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:8081/eureka/
即两个节点相互注册,形成集群
因为是在本地搭建的多个节点注册在同一台服务器上,所以还需要在C:\Windows\System32\drivers\etc\hosts文件中添加peer1,peer2的转换,即peer1、peer2都指向本地IP
修改完如上配置后重新clean、编译打包eureka服务端项目,通过java -jar分别启动不同的端口号
点击IDEA中的Terminal即可进入命令启动窗口
启动指定端口号的注册服务:
java -jar D:\myInfos\springEureka_server\target\eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
注意:jar包路径必须是绝对路径,不然会报如下错误:
启动peer1:
出现如下界面,证明已成功启动:
浏览器访问:http://peer1:8081
你会发现与单节点注册中心不一样,DS Replicas 指向了peer2,registered-replicas 也指向了pee2
重新开启一个Terminal窗口,点击启动pee1 Terminal窗口中的+号,如下图,打开新的Terminal窗口
pee2启动步骤及检查方式请参考pee1
修改Eureka客户端配置,注册到多个注册中心
eureka.client.serviceUrl.defaultZone=http://peer1:8081/eureka/, http://peer2:8082/eureka/
spring.application.name=hello-service
重新启动Eureka客户端应用,刷新peer1、peer2的页面,会发现hello-service已同时注册到peer1、peer2上
peer1出现EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE. eureka自我保护机制的告警
原因分析:
这个是Eureka的自我保护机制。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。
Eureka server和client之间每隔30秒会进行一次心跳通信,告诉server,client还活着。由此引出两个名词:
Renews threshold:server期望在每分钟中收到的心跳次数
Renews (last min):上一分钟内收到的心跳次数
禁止注册server自己为client,不管server是否禁止,阈值(threshold)是1。client个数为n,阈值为1+2*n(此为一个server且禁止自注册的情况)
如果是多个server,且开启了自注册,那么就和client一样,是对于其他的server来说就是client,是要*2的
阈值:1+2*1
renews:
1)自注册 2 + 2*1
2)非自注册:2*1
Eurake有一个配置参数eureka.server.renewalPercentThreshold,定义了renews 和renews threshold的比值,默认值为0.85。当server在15分钟内,比值低于percent,即少了15%的微服务心跳,server会进入自我保护状态,Self-Preservation。在此状态下,server不会删除注册信息,这就有可能导致在调用微服务时,实际上服务并不存在。
这种保护状态实际上是考虑了client和server之间的心跳是因为网络问题,而非服务本身问题,不能简单的删除注册信息
stackoverflow上,有人给出的建议是:
1、在生产上可以开自注册,部署两个server
2、在本机器上测试的时候,可以把比值调低,比如0.49
3、或者简单粗暴把自我保护模式关闭
eureka.server.enableSelfPreservation=false
总结:
1.不管是单节点注册中心还是集群,都必须保证客户端配置的注册中心地址与Eureka Server(注册中心)的一致
2.集群的好处是其中一个节点宕机后服务能正常被调用,为了安全起见,集群服务器最好是多台机器(生产上一般是多台机器),这样即使服务器出现异常问题,也能保证服务正常
3.如果我们不想使用主机名来定义注册中心的地址,也可以使用IP地址的形式,但是需要配置文件中增加配置参数eureka.instance.prefer-ip-address=true,该默认为false。然后当应用程序向eureka注册时,它将使用IP地址而不是主机名