springcloud系列学习笔记目录参见博主专栏 spring boot 2.X/spring cloud Greenwich。
由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。文章所有代码都已上传GitHub:https://github.com/liubenlong/springcloudGreenwichDemo
本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;
在spring cloud Greenwich 学习笔记(一)spring cloud eureka ribbon 服务注册与发现和spring cloud Greenwich 学习笔记(二)spring cloud eureka Feign 服务注册与发现两篇文章中介绍了如何使用eureka注册中心。但是存在一个问题,eureka是单点的,肯定不适用于现在的分布式高可用系统。所以我们需要配置eureka集群。
在原有springcloud-eureka-server
项目基础上copy一份,改名为springcloud-eureka-server-cluster
测试。
这里我们顺便将eureka密码验证服务添加上。
pom文件中添加spring-boot-starter-security
用于安全验证。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
修改application.yml,这里我们单机模拟三个eureka服务,并且开启密码安全验证。与之前的配置区别是将fetch-registry
和register-with-eureka
都还原为了默认值true(其含义见下面注释)。完整配置如下:
spring:
application:
name: springcloud-eureka-server-cluster
--- #注意这里是三个"减号"
spring:
profiles: eureka1 # 通过profile指定启动服务
security: # 配置安全验证
user:
name: admin
password: 123456
server:
port: 8001
eureka:
server:
enable-self-preservation: false # 测试时关闭自我保护机制,保证不可用服务及时踢出【生成环境不要打开】
instance:
hostname: eureka1
client:
serviceUrl:
defaultZone: http://admin:123456@eureka2:8002/eureka/,http://admin:123456@eureka3:8003/eureka/
# fetch-registry: true # 表示是否从eureka server获取注册信息,如果是单一节点,不需要同步其他eureka server节点,则可以设置为false,但此处为集群,应该设置为true,默认为true,可不设置
# register-with-eureka: true # 表示是否将自己注册到eureka server,因为要构建集群环境,需要将自己注册到及群众,所以应该开启。默认为true,可不显式设置。
---
spring:
profiles: eureka2
security:
user:
name: admin
password: 123456
server:
port: 8002
eureka:
server:
enable-self-preservation: false # 测试时关闭自我保护机制,保证不可用服务及时踢出
instance:
hostname: eureka2
client:
serviceUrl:
defaultZone: http://admin:123456@eureka1:8001/eureka/,http://admin:123456@eureka3:8003/eureka/
---
spring:
profiles: eureka3
security:
user:
name: admin
password: 123456
server:
port: 8003
eureka:
server:
enable-self-preservation: false # 测试时关闭自我保护机制,保证不可用服务及时踢出
instance:
hostname: eureka3
client:
serviceUrl:
defaultZone: http://admin:123456@eureka1:8001/eureka/,http://admin:123456@eureka2:8002/eureka/
启动类不变:
@SpringBootApplication
@EnableEurekaServer //启用EurekaServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
由于Spring Cloud 2.0 以上的security默认启用了csrf
检验,要在eurekaServer端配置security的csrf检验为false。
否则会报错com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
2019-02-14 14:04:13.033 WARN 33668 --- [nfoReplicator-0] c.n.discovery.InstanceInfoReplicator : There was a problem with the instance info replicator
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.8.jar:1.9.8]
at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.8.jar:1.9.8]
at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) ~[eureka-client-1.9.8.jar:1.9.8]
at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.9.8.jar:1.9.8]
at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.8.jar:1.9.8]
at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:829) ~[eureka-client-1.9.8.jar:1.9.8]
at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:121) ~[eureka-client-1.9.8.jar:1.9.8]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
为了解决上述问题,需要手动关闭csrf
服务:
@EnableWebSecurity
public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
super.configure(http); // 这一句必须要加上的,否则直接关闭密码验证服务了
}
}
接下来启动服务。上面application.yml配置中配置了三个eureka服务,端口分别为8001,8002,8003。每个eureka服务都注册到了另外两个eureka服务上。
分别启动三个服务,我这里使用的是IDEA,分别制定active Profiles 即可。
在集群未全部启动完成时,会报下面的错误,无需关心,是因为我们这里是部署的eureka集群,有服务没有启动,这里连接不上,所有服务全部启动就好了。
启动完成后控制台会输出相关日志,三台服务都处于UP
状态:
访问其中一台集群http://eureka1:8002/
,由于我们开启了安全校验,所以之类要登陆
输入配置文件中的用户名密码,及你如eureka控制台。看到三个服务都注册上了,其中两个是副本。
THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
这句话的意思是自我保存模式已关闭,在出现网络故障等原因时,可能无法提供高可用服务
。这是由于我们再配置文件中设置了eureka.server.enable-self-preservation=false
导致的,这个配置关闭自我保护机制,保证不可用服务及时踢出。该配置仅仅适用于测试环境,生产环境不要使用。
上面eureka集群已经搭建好,我们之前的客户端是使用的defaultZone: http://localhost:8080/eureka/
单机版,我们现在将其改为集群配置:defaultZone: http://admin:123456@eureka2:8001/eureka/,http://admin:123456@eureka3:8002/eureka/,http://admin:123456@eureka2:8003/eureka/
。
这里读者可以自行测试,本人已经测试通过。
上面我们是在本机开发工具IDEA测试的,生产环境上肯定是会部署在多态Linux服务器上。这里给出部署的脚本,很简单,指定一下profile即可:
java -jar 生成的jar包名称.jar --spring.profiles.active=eureka1
java -jar 生成的jar包名称.jar --spring.profiles.active=eureka2
java -jar 生成的jar包名称.jar --spring.profiles.active=eureka3
springcloud系列学习笔记目录参见博主专栏 spring boot 2.X/spring cloud Greenwich。
由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。文章所有代码都已上传GitHub:https://github.com/liubenlong/springcloudGreenwichDemo
本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;