0%

AOP开启注解

在使用注解@Aspect来进行AOP操作时,需要在xml中进行配置

1
2
<!-- 使@Aspect注解生效 -->
<aop:aspectj-autoproxy/>

创建BeanFactory时obtainFreshBeanFactory()在解析xml加载BeanDefinition中,执行parseBeanDefinitions方法进行解析发现其内有逻辑是

1
delegate.parseCustomElement(ele)

即进行自定义标签的解析,会去META-INF/spring.handlers中寻找对应的handler,该标签的namespace是http://www.springframework.org/schema/aop,去spring.handlers中找到对应的记录

1
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
1
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

还有一个配置是spring.schemas,以找到对应的xsd文件

1
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd

然后执行该handler中的init方法

1
2
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
namespaceHandler.init();

即执行AopNamespaceHandler#init

阅读全文 »

消息重复消费问题

为什么会出现重复消费?

原因一:生产者消息重复发送

可能出现的情况

  • 生产者发送消息给消息中间件,消息中间件收到消息并进行存储,但是此时消息中间件出现了问题,导致生产者没有收到发送成功的返回,导致的消息重试
  • 消息中间件因为负载高响应变慢,成功把消息存储到消息存储后,返回成功超时,导致的消息重试
  • 消息中间件将消息成功写入消息存储后,在返回结果时网络出现问题,导致消息重试

解决方案

  • 在消息中加入一个唯一id,这样消息重试也不会造成数据重复,在进行处理时需要判断id

原因二:消息中间件投递时重复

  • 消息被投递到消费者时,处理完毕后应用出现问题,没有返回消费成功,此时消息中间件再次投递
  • 消息被投递到消费者进行处理,处理完毕后网络出现问题,导致消息中间件没有收到消息处理结果,再次投递
  • 消息被投递到消费者进行处理,处理时间超时,导致再次投递
  • 消息被投递到消费者进行处理,处理完毕后消息中间件出现问题,没有收到消息处理结果,再次投递
  • 消息被投递到消费者进行处理,处理完毕后消息中间件收到结果,但是消息存储故障,没有更新投递状态,再次投递

解决方案

  • 在消息中加入一个唯一id,这样消息重试也不会造成数据重复,在进行处理时需要判断id

消息丢失问题

消息丢失主要有三种可能

  • 生产者丢失数据
  • 消息队列丢失数据
  • 消费者丢失数据

下面来分别说明这三种情况

生产者丢失数据

在生产者发送数据时,为了减少IO,其实是将多个请求进行合并发送的,被合并的数据存在本地buffer中,这里可以先在事务中进行数据库存储,然后在进行消息发送,这样就算发送失败也可以使用定时来进行消息发送。然后使用callback来确认消息是否发送到消息队列,如果没有发送成功可以来进行重试操作

阅读全文 »

循环依赖

spring中将循环依赖处理分为了两种情况

构造器循环依赖

使用构造器注入构成循环依赖,这种方式无法进行解决,抛出了BeanCurrentlyInCreationException异常

在创建bean之前会进行检测

1
2
3
4
5
6
7
protected void beforeSingletonCreation(String beanName) {
// inCreationCheckExclusions中是否存在当前正在创建的bean
// 并且singletonsCurrentlyInCreation是否可以添加成功(也就是singletonsCurrentlyInCreation中是否存在正在创建的bean)
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
阅读全文 »

IP地址

有很多好用的网络工具,如ping、traceroute等

ping

ping是最好用的网络工具之一,可以判断一台网络上的计算机是否可达

1
2
3
4
5
6
7
8
9
10
11
ping zhhll.icu
PING isfox-github-io.vercel.app (76.223.121.104): 56 data bytes
64 bytes from 76.223.121.104: icmp_seq=0 ttl=107 time=100.365 ms
64 bytes from 76.223.121.104: icmp_seq=1 ttl=107 time=107.179 ms
64 bytes from 76.223.121.104: icmp_seq=2 ttl=107 time=106.974 ms
64 bytes from 76.223.121.104: icmp_seq=3 ttl=107 time=106.934 ms
64 bytes from 76.223.121.104: icmp_seq=4 ttl=107 time=105.350 ms
64 bytes from 76.223.121.104: icmp_seq=5 ttl=107 time=105.105 ms
--- isfox-github-io.vercel.app ping statistics ---
6 packets transmitted, 6 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 100.365/105.318/107.179/2.359 ms
阅读全文 »