艰辛的学习之路:异常——Field registration in org.springframework.cloud.client.serviceregistry.ServiceRegistryAu
文章目录引言环境异常报错异常原因解决过程总结引言在学习Spring Cloud 中冲 Eureka 服务注册切换到 openFeign 服务注册时,报错有2个服务注册自动配置类,出现在 order_service 的启动报错中, 前面从 eureka 切换到 consul 服务注册,现在又需要切换到 openFeign 的形式,但是还是存在 consul 的注册类环境Maven 依赖 pom.xm
·
引言
在学习Spring Cloud 中冲 Eureka 服务注册切换到 openFeign 服务注册时,报错有2个服务注册自动配置类,出现在 order_service 的启动报错中, 前面从 eureka 切换到 consul 服务注册,现在又需要切换到 openFeign 的形式,但是还是存在 consul 的注册类
环境
- Maven 依赖 pom.xml
<dependencies>
<!-- spring cloud 整合 openFeign 组件-->
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-core</artifactId>
<version>8.18.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
- 几个微服务配置文件 application.properties
// 第一个 order_service 的 配置文件
server.port=9002
server.address=127.0.0.1
# 服务
spring.application.name=service-order
# 数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_test
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.open-in-view=true
# eureka 配置
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:9000/eureka/
eureka.instance.ip-address=${server.address}
eureka.instance.instance-id=${server.address}:${server.port}
# 向注册中心注册服务ID,发送心跳
eureka.instance.lease-renewal-interval-in-seconds=5
# 续约到期时间
eureka.instance.lease-expiration-duration-in-seconds=10
# 配置Ribbon 负载均衡策略
# Ribbon 创建一个Http请求连接的超时时间
service-product.ribbon.ConnectionTimeout=250
# Ribbon 的数据读取超时时间
service-product.ribbon.ReadTimeout=1000
# 是否对所有的操作进行重试
service-product.ribbon.OkToRetryOnAllOperations=true
# 切换实例的重复次数
service-product.ribbon.MaxAutoRetriesNextServer=1
# 对当前实例的重复次数
service-product.ribbon.MaxAutoRetries=1
# Consul 配置
# consul 服务器主机地址
#spring.cloud.consul.host=127.0.0.1
## consul 服务器 Ip 地址
#spring.cloud.consul.port=8500
## 基于服务发现的配置:
## 是否需要注册
#spring.cloud.consul.discovery.register=true
## 注册的实例 id (唯一标识)
#spring.cloud.consul.discovery.instance-id=${spring.application.name}:${server.port}
## 服务的名称
#spring.cloud.consul.discovery.service-name=${spring.application.name}
## 服务的端口
#spring.cloud.consul.discovery.port=${server.port}
## 服务的请求 ip 地址
#spring.cloud.consul.discovery.ip-address=${server.address}
## 指定开启服务 ip 地址注册
#spring.cloud.consul.discovery.prefer-ip-address=true
## 开启 consul 健康心跳检查
#spring.cloud.consul.discovery.heartbeat.enabled=true
- openFeign Client 接口
//order service 的 openFeign Client 接口
package com.hk.order.feign;
import com.hk.product.entity.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @author : HK意境
* @ClassName : ProductFeignClient
* @date : 2021/7/22 12:46
* @description : 声明需要调用的微服务名称:
* @FeignClient
* name : 服务提供者名称
* @Todo :
* @Bug :
* @Modified :
* @Version : 1.0
*/
@FeignClient(name = "service-product")
public interface ProductFeignClient {
/**
* 配置需要调用的微服务接口
*/
@RequestMapping(value = "/product/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable("id")int id) ;
}
- 几个微服务主启动类
// OrderApplication 启动类
/**
* @author : HK意境
* @ClassName : OrderApplication
* @date : 2021/7/19 19:35
* @description :
* @Todo :
* @Bug :
* @Modified :
* @Version : 1.0
*/
@SpringBootApplication
// 服务发现
//@EnableDiscoveryClient
//激活 Feign
@EnableFeignClients
@EnableEurekaClient
@ImportAutoConfiguration({RibbonAutoConfiguration.class, FeignRibbonClientAutoConfiguration.class, FeignAutoConfiguration.class})
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class ,args) ;
}
}
- 微服务Controller 层面
package com.hk.order.controller;
import com.hk.order.feign.ProductFeignClient;
import com.hk.product.entity.Product;
import com.hk.product.service.ProductService;
import com.hk.product.service.impl.ProductServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
/**
* @author : HK意境
* @ClassName : OrderController
* @date : 2021/7/19 19:36
* @description :
* @Todo :
* @Bug :
* @Modified :
* @Version : 1.0
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private ProductFeignClient productFeignClient;
@Autowired
private RestTemplate restTemplate ;
/***
* 注入 DiscoveryClient
* spring cloud 提供的获取元数据的工具类
* 调用方法获取服务的元数据信息
*/
@Autowired
private DiscoveryClient discoveryClient;
/***
* 基于 Ribbon 的形式调用远程微服务
* 1.使用 @LoadBalanced 注解声明 RestTemplate
* 2.使用服务名替换IP 地址
*
* @param id
* @return
*/
@RequestMapping("/buy/{id}")
public Product buy(@PathVariable("id")int id){
/*//以调用服务名称获取说有元数据
List<ServiceInstance> serviceInstances = discoveryClient.getInstances("service-product");
//获取唯一的一个元数据
ServiceInstance instance = serviceInstances.get(0);
//根据元数据中的主机地址和端口号拼接请求的微服务URL
String url = "http://" +instance.getHost() + ":"+instance.getPort() + "/product/1";
Product product = restTemplate.getForObject(url, Product.class);*/
/* String serviceName = "service-product" ;
String url = "http://" + serviceName + "/product/1" ;
System.out.println(url);
Product product = restTemplate.getForObject(url, Product.class);*/
//通过 openFeign 方式调用
Product product = productFeignClient.findById(id);
return product ;
}
}
异常报错
主要翻译过来就是只需要一个服务注册自动配置类, 但是提供了2个自动的服务注册器,一个是 eureka ,一个是 consul
***************************
APPLICATION FAILED TO START
***************************
Description:
Field registration in org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration$ServiceRegistryEndpointConfiguration required a single bean, but 2 were found:
- eurekaRegistration: defined in BeanDefinition defined in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.class]
- consulRegistration: defined by method 'consulRegistration' in class path resource [org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.class]
异常原因
主要翻译过来就是只需要一个服务注册自动配置类, 但是提供了2个自动的服务注册器,一个是 eureka ,一个是 consul ,
针对这个原因, 推导因该是 以下几个原因:
- 导入的依赖中还剩下了 consul 的依赖没有清除完成
- 在这个模块中还配置了 consul 的注册服务,及其注解, 编码等
- 系统缓存, IDEA 缓存原因
解决过程
有了以上原因以及可能情况的分析一个一个进行解决:
- 第一先查看是否是 consul 的依赖缓存:果然在依赖中还是剩下了 consul 的 jar 包依赖, 尝试去除
果然去除之后,没有再次报错注册中心多个配置类的问题了,变成了另一个异常, 这也算解决了:
- 接下来是第二种尝试方案: 既然说自动装配的类重复了,那就根据spring boot 的自动装配机制, 去除这个重复的自动装配类就好了, 在配置文件中添加如下配置去除 consul 的自动注册装配类的加载
spring.autoconfigure.exclude: org.springframework.cloud.netflix.eureka.ConsulAutoServiceRegistrationAutoConfiguration
总结
总感觉 Spring Cloud 方面的依赖总是存在一堆奇奇怪怪的问题和错误, 依赖老是存在无法导入的问题,要么导入了不能用,报错,导入不齐全等
更多推荐
已为社区贡献1条内容
所有评论(0)