单元测试引入hsqldb探索 为了提高代码和产品质量,我们网站的大部分产品都接入了单测平台,任何任务在提测前都要执行整个提测工程的单元测试,测试结果全部通过并且覆盖率统计等指标达标之后才能通过提测申请。这当然对于提高产品代码质量是有非常大的好处的,有助于识别代码中的bug。但是在执行的过程中可不是那么顺利的,主要体现在有时单测执行失败并不是代码有什么bug,而是单测依赖的数据发生了变化导致单测的执行结果和预期的结果不一样ass...
一个传递依赖导致的应用崩溃 问题最近我们有个应用合并了一个任务的代码之后应用无法启动,报下面的错误:Caused by: java.lang.NoSuchMethodError: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.modulesToInstall([Lcom/fasterxml/jackson/databind/Mo...
nginx健康检查导致的问题 最近有次web应用版本上线,出现了一个可怕的事情,上线之后所有http请求都报502,但是之前在测试环境和预发布环境测试功能是没有任何问题的。 502错误说明是tomcat应用出问题了,查看tomcat启动日志,没有任何异常,日志显示应用已经正常启动成功了,ssh连上服务器,通过wget调用接口发现是可以正常响应的,这就更说明了tomcat应用本身是没问题的。但是查看应用的localhost_a...
dubbo框架中一行日志代码引发的超时问题 前一段时间有测试反馈,我负责的一个dubbo接口调用超时,而是是稳定必现的超时。拿到问题之后第一件事当然是分析代码所有可能性能瓶颈的地方,然后并没有收获,我们的接口超时时间设置的是5s,然后单测我们的接口时间只有几十ms。相同的数据,测试怎么会出现这么大的差异呢。难道是dubbo接口的配置问题?找我们的dubbo老司机检查了一遍并没有检查出配置问题,而且工程日志也出现任何可疑的错误信息。而且换了几个
Spring框架由ConditionalOnMissingBean注解引发的问题 问题描述最新负责的工程在做dubbo配置disconf静态配置托管优化,由一个StaticConfigPropertiesFactoryBean来读取静态配置,它是PropertiesFactoryBean的一个子类,读取到的所有配置放在一个Properties中。 dubbo配置直接引用这个Properties的值。像下面这样,dubbo接口的group通过disconf的静态配置项dubb
dubbo源码浅析(五)-远程服务调用流程 消费端调用远程服务接口时,使用上和调用普通的java接口是没有任何区别,但是服务消费者和提供者是跨JVM和主机的,客户端如何封装请求让服务端理解请求并且解析服务端返回的接口调用结果,服务端如何解析客户端的请求并且向客户端返回调用结果,这些框架是如何实现的,下面就来看下这部分的代码。 消费端调用提供端服务的过程要执行下面几个步骤: 1. 消费端触发请求 2. 消费端请求编码 3.
dubbo源码浅析(四)-服务消费者初始化 在分析标签解析的时候知道框架会把dubbo:reference解析成一个ReferenceBean,它是一个FactoryBean,消费者的初始化在它的init方法中执行,这个方法在两种情况下会被调用: 1. 消费者设置了立即初始化(init属性设置成true),那么bean加载时会立刻调用消费者初始化。 2. 消费者bean被使用者调用时,调用getObject->get->init
dubbo源码浅析(三)-服务提供者初始化 dubbo服务提供者由dubbo:service来定义,从前面可以看到,Spring把dubbo:service解析成一个ServiceBean,ServiceBean实现了ApplicationListener和InitializingBean接口,ServiceBean有个核心方法export,在这个方法中初始化服务提供者并且暴露远程服务。这个方法在bean初始化或容器中所有bean刷新完毕时
dubbo源码浅析(二)-标签解析 前面了解了dubbo的插件化机制之后,接下来进入正题,研究一下dubbo的核心原理,由于dubbo的功能配置较多,为了更高效的研读代码,在阅读的过程中尽量忽略一些细节,重点关注它的主干流程,主干了解清楚之后再去分析它的一些细节功能就更轻松了,否则容易陷入各种细枝末节不能自拔让整个代码的阅读周期变得冗长无比效率大打折扣。 Dubbo框架中,服务提供者和服务消费是两个核心角色,所以主要通过服务提供者
dubbo源码浅析(一)-插件化机制 在前东家一直从事偏客户端相关的工作,进了新东家之后终于有机会从事大型的分布式系统开发,在微服务大行其道的今天,dubbo框架作为一款优秀的开源RPC框架使用非常广泛,在使用dubbo的这几个月里,用零碎的空闲时间对dubbo框架的源码浅读了一番,由于平时工作忙加班比较多,所有历时几个月才把读代码的过程整理出来,打算分成几篇把这个过程共享记录下来。
Netty内存池原理分析 为了避免频繁的内存分配给系统带来负担以及GC对系统性能带来波动,Netty4提出了全新的内存管理,使用了全新的内存池来管理内存的分配和回收。内存池这块的代码晦涩难懂,而且几乎没有注释,所以阅读起来比较费力,特别是以前没有接触过内存分配算法的阅读起来更为蛋疼,好在经过几个晚上的努力,终于捋出了一些端倪,特来此记录一番。Netty4的内存池集大家之精华,参考了各路英雄豪杰的优秀思想,它参考了sla
Netty为啥可靠(三) 连接中断处理在客户端和服务端建立起连接之后,如果连接发生了意外中断,Netty也会及时释放连接句柄资源(因为TCP是全双工协议,通信双方都需要关闭和释放Socket句柄才不会发生句柄的泄漏,如不经过特殊处理是会发生句柄泄露的),原理如下:在读取数据时会调用io.netty.buffer.AbstractByteBuf.writeBytes(ScatteringByteChannel, in
Netty为啥可靠(二) Selector空轮询处理在NIO中通过Selector的轮询当前是否有IO事件,根据JDK NIO api描述,Selector的select方法会一直阻塞,直到IO事件达到或超时,但是在Linux平台上这里有时会出现问题,在某些场景下select方法会直接返回,即使没有超时并且也没有IO事件到达,这就是著名的epoll bug,这是一个比较严重的bug,它会导致线程陷入死循环,会让CPU飙
Netty为啥可靠(一) NIO闲聊自从JAVA1.4推出NIO起,JAVA网络编程进入了一个全新的时代,传统网络IO(OIO)是傻等式的,一旦IO操作发起,那么用户线程就陷入很傻很天真的等待中,直到IO操作结束或者发生了断连,而NIO则要聪明许多是事件触发式的,只有当前有IO事件发生了,才会通知用户线程执行IO操作,当前操作结束之后不会阻塞等待可以执行其他的业务操作等待下一次事件,就好比上银行取钱,一种方式排队傻等直
基于Netty的Redis客户端-Nedis 最近温习了一遍Redis命令,忧伤的是很多东西已交还给老师,正好赶上antirez大神在愚人节发布了Redis 3.0,Redis终于有了支持集群的正式版本,于是心血来潮决定自己实现一个Redis客户端来抚慰我这颗忧伤的心灵。Jedis已经足够强大,它的网络连接是基于阻塞式IO,实现非常简单易懂,但是OIO和NIO相比性能上有劣势,于是决定通过NIO来实现和Redis服务器的网络连接,现在
《Redis设计与实现》学习笔记-Lua脚本 Redis从2.6开始支持Lua脚本,和事务的功能类似,可以通过Lua脚本原子的执行多个Redis命令。Redis提供了EVAL和EVALSHA命令执行lua脚本。创建并修改Lua坏境Redis在服务器内嵌了一个Lua坏境,并进行了一系列的修改,从而确保这个Lua坏境可以满足Redis服务器的需要,通过下列步骤创建并修改Lua坏境:创建一个基础Lua坏境,通过调用Lua的C API
《Redis设计与实现》学习笔记-发布订阅与事务 发布与订阅Redis通过发布订阅提供一对多甚至是多对多的节点消息通信,发布订阅由PUBLISH、SUBSCRIBE、PSUBSCRIBE、PUBSUB等命令组成。SUBSCRIBE命令:订阅某频道,在redisServer结构中通过pubsub_channels字典属性保存当前服务器所有频道的订阅关系,字典键时频道名称,字典值是一个链表,记录了所有订阅这个频道的客户端。UNSUBSCR
《Redis设计与实现》学习笔记-集群 Redis也可通过集群来实现分布式,通过分片进行数据共享,并提供复制和故障转移。当前Redis版本的集群功能还没有正式发布,目前只是一个不稳定的分支,据说快要正式发布了。添加集群节点服务器节点通过执行CLUSTER MEET 命令把指定的服务器添加到当前集群中,通过CLUSTER NODES来查询当前集群中的所有节点信息,当cluster-enabled配置选项设成yes时,说明该服务器
《Redis设计与实现》学习笔记-Sentinel(哨岗、哨兵) Sentinel是Redis的高可用性解决方案,由一个或多个Sentinel实例组成Sentinel系统,可以用来监视任意多个主服务器和主服务器下的所有从服务器,当监视到主服务器下线之后会自动将下线主服务器下的从服务器升级为新的主服务器,由新主服务器代替已下线主服务器处理命令请求。Sentinel是一个特殊的Redis服务器实例,Redis由一个或多个Sentinel实例构成Sentinel系