SpringCloud Eureka Server 高可用环境搭建遇到的问题
Eureka Server 高可用环境需要部署两个Eureka server,它们互相向对方注册。如果在本机启动两个Eureka需要注意两个Eureka Server的端口要设置不一样,这里我们部署一个Eureka Server工程,将端口可配置,制作两个Eureka Server启动脚本,启动不同的端口。
1.application.yml文件配置eureka
server:
port: ${PORT:50101} #服务端口
spring:
application:
name: xc-govern-center #指定服务名
eureka:
client:
registerWithEureka: true #服务注册,是否将自己注册到Eureka服务中
fetchRegistry: true #服务发现,是否从Eureka中获取注册信息
serviceUrl: #Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)
defaultZone: ${EUREKA_SERVER:http://eureka02:50102/eureka/}
server:
enable-self-preservation: false #是否开启自我保护模式
eviction-interval-timer-in-ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
instance:
hostname: ${EUREKA_DOMAIN:eureka01}
2 在IDEA中制作启动脚本
注意必须复制文件后修改文件,不能直接修改原来的启动脚本,否则将会发现错误,可能导致一个注册中心可以启动,另一个不能正常启动。
2.1 复制文件
2.2 配置环境变量
在Environment选项的VM options中配置:
eureka01:
-DPORT=50101
-DEUREKA_SERVER=http://eureka02:50102/eureka/
-DEUREKA_DOMAIN=eureka01
eureka02:
-DPORT=50102
-DEUREKA_SERVER=http://eureka01:50101/eureka/
-DEUREKA_DOMAIN=eureka02
2.3 修改hosts文件
hosts文件位于系统盘C:\Windows\System32\drivers\etc中,hosts是一个没有扩展名的系统文件,hosts作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,对大家操作电脑有一定帮助!
添加以下内容:
127.0.0.1 eureka01
127.0.0.1 eureka02
完成以上所有操作后,启动eureka01和eureka02,发现不能启动。报错内容如下(部分内容):
java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117) ~[na:na]
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) ~[na:na]
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:na]
at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68) ~[na:na]
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138) ~[na:na]
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:na]
at java.base/sun.reflect.generics.repository.ClassRepository.computeSuperInterfaces(ClassRepository.java:117) ~[na:na]
at java.base/sun.reflect.generics.repository.ClassRepository.getSuperInterfaces(ClassRepository.java:95) ~[na:na]
at java.base/java.lang.Class.getGenericInterfaces(Class.java:1112) ~[na:na]
at com.sun.jersey.core.reflection.ReflectionHelper.getClass(ReflectionHelper.java:629) ~[jersey-core-1.19.1.jar:1.19.1]
at com.sun.jersey.core.reflection.ReflectionHelper.getClass(ReflectionHelper.java:625) ~[jersey-core-1.19.1.jar:1.19.1]
at com.sun.jersey.core.spi.factory.ContextResolverFactory.getParameterizedType(ContextResolverFactory.java:202) ~[jersey-core-1.19.1.jar:1.19.1]
....
经过在网上查询资料发现其根本原因是:Java 9引入了模块的概念,默认情况下,java.se聚合模块可在类路径(或更确切地说,模块路径)上使用。正如其名称所暗示的,java.se汇聚模块并没有包括那些与Java 6/7/8传统上捆绑了Java EE的API。
项目环境是Java9,因此会发生错误。
解决方案一:在pom文件中引入Java8中的依赖
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
方案二:运行时,指定命令–add-modules java.xml.bind(dirty solution)
方案三:更改运行环境
详见 https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j
经测试发现方案一添加后依然报错,maven配置的镜像为阿里云,在导入jaxb-runtime报红,原因未知。然后采用方案三发现可以有效的解决该问题。在编辑配置时更改JRE环境为1.8。然后启动eureka01和eureka02后正常运行。