集成美团点评cat报错,Unable to get instance of Logger, please make sure the environment was setup correctly!

问题:

  • 这两天在集成美团点评cat监控平台时,一直报错,无法上报信息。

解决过程:

  • 一开始以为是配置文件配置有问题,找了半天没发现啥问题
  • 又想着是不是jar包冲突的问题,因为看到有人说netty版本的问题,不过试了一下不管用
  • 因为是比较老的项目,不知道是不是有其他jar包影响到了cat,于是新建了个springboot项目,同样的配置,通过Application#main方法居然成功了,说明配置没问题。一个是springboot、一个是普通spring项目感觉也没啥差别。。。

半天过去了,没辙了,,,后来第二天google了一下,就找到个cat的issue:https://github.com/dianping/cat/issues/1071,有个回复说是使用了tomcat7插件启动就会有问题,改成jetty、tomcat容器就可以了。

试了一下就可以了,,,,具体原因没细分析。

所以解决方法之一:

  • 使用tomcat容器启动项目,而不是tomcat7的maven插件

报错信息如下:

java.lang.RuntimeException: Unable to get instance of Logger, please make sure the environment was setup correctly!
	at org.unidal.initialization.DefaultModuleContext.setup(DefaultModuleContext.java:122)
	at org.unidal.initialization.DefaultModuleContext.<init>(DefaultModuleContext.java:30)
	at com.dianping.cat.Cat.initialize(Cat.java:199)
	at com.dianping.cat.Cat.checkAndInitialize(Cat.java:79)
	at com.dianping.cat.Cat.getProducer(Cat.java:177)
	at com.dianping.cat.Cat.logEvent(Cat.java:325)
	at redis.clients.jedis.Connection.sendCommand(Connection.java:90)
	at redis.clients.jedis.BinaryClient.ping(BinaryClient.java:88)
	at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:79)
	at redis.clients.jedis.JedisFactory.validateObject(JedisFactory.java:100)
	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:488)
	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
	at redis.clients.util.Pool.getResource(Pool
### 可能的原因分析 当使用 `@Value` 注解后导致嵌入式 Tomcat 启动失败时,通常可能是由于以下几个原因引起的: 1. **未正确注入属性值** 如果 `application.properties` 或 `application.yml` 文件中的键名与 `@Value` 注解绑定的变量不匹配,则可能导致依赖注入失败。这种情况下,Spring Boot 会在初始化阶段抛出异常,从而阻止 Tomcat 容器正常启动[^1]。 2. **延迟加载问题** 当某些 Bean 需要提前初始化而其依赖项尚未准备好时,可能会引发类似的错误。如果某个被 `@Value` 注解标记的字段是其他组件所必需的,但在应用上下文完全加载之前就尝试访问它,就会触发此问题[^2]。 3. **代理模式冲突** 在特定场景下(例如分布式事务管理框架 Seata),可能存在代理机制上的冲突。Seata 默认采用 CGLIB 动态代理技术来增强服务调用链路追踪能力;然而对于一些特殊的数据源对象(如 ShardingSphere 提供的支持分库分表功能的数据源实现类),CGLIB 并不能很好地处理它们的序列化需求。因此需要通过调整配置强制切换到 JDK 原生接口级别的动态代理方式以规避此类风险[^3]。 针对以上可能的情况可以采取如下措施解决问题: #### 解决方案一:检查配置文件并修正键名拼写错误 确保项目根目录下的资源文件(application.properties或者application.yml)里定义了相应的参数名称,而且这些名字正好对应上了那些用了@value标签修饰过的成员变量. ```properties # application.properties example my.custom.property=valueForProperty ``` 然后在代码里面这样获取该值: ```java private String customPropertyValue; @Autowired public void setCustomPropertyValue(@Value("${my.custom.property}") final String value){ this.customPropertyValue = value; } ``` #### 解决方案二:推迟Bean实例化的时机直到所有的必要条件都满足为止 可以通过设置Lazy Initialization标志位让spring framework稍后再去创建那个含有@value标注域的对象实例. 比如下面的例子展示了如何声明一个懒加载的服务bean : ```java @Service @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS) @Lazy(value=true) public class MyService { private static final Logger logger = LoggerFactory.getLogger(MyService.class); @Autowired(required=false) public MyService(@Value("#{environment['MY_ENV_VAR'] ?: 'default'}")String envSpecificConfig){ //do something useful here... System.out.println(envSpecificConfig); } } ``` 另外一种做法就是把需要用到外部环境变量的地方封装成单独的一个Factory Method形式返回目标类型的实例给容器注册进去即可. #### 解决方案三:更改使用的AOP Proxy Strategy 如果是因Seata之类的中间件引入造成的兼容性难题的话,则按照官方文档指示修改对应的yml/json格式配置项内容如下所示: ```yaml seata: enable-auto-discovery: false tx-service-group-name : my_test_tx_group service : vgroup-mapping : my_test_tx_group : default disable-global-tx : false config : type : file file : name : seata-config.txt registry : type : nacos nacos : server-addr : localhost:8848 namespace : "" cluster : default username : "" password : "" use-jdk-proxy: true # key point ! ``` 最后重启应用程序验证效果.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值