标签 Java 下的文章

不要自己造轮子

Don't repeat yourself

DRY这句话大家可能耳朵都听出茧子了。不过,这个确实是非常重要的一个填坑要诀。

拿正常的开发(非填坑)来说,使用别人造好的轮子可以大大提高效率和开发进度。
我上次用的别人的大轮子是开发微信公众号和小程序的时候,用的wechat这个开源lib。使得集成微信的工作量大大减少,不必看微信那么多的文档和接口。

专门拿填坑来说,使用别人造好的轮子比正常开发要显得还重要一些。当然这里的轮子主要是原来工程中使用的轮子了。尽量使用工程中原来使用的轮子,别自己造,更别使用其他人的轮子。

我见过最常最轮子的方法就是类似于StringUtils和CollectionUtils这种,用来判断empty,用来split等。

- 阅读剩余部分 -

上篇文章提到了生成唯一的短字符串,应用在给每个用户生成一个唯一的邀请码,这个可以扩展到给每个商品生成一个唯一的编号,给每个地点生成一个唯一的标识等等。

但是,唯一的短字符串还有另外一个场景,就是靓号,比如说QQ靓号,直播间的房间号,这些场景下,如果随机生成一些字符串可能并不如人意,需要将某些靓号整理出来,专门给运营发放。

最先想到的就是把靓号全部找出来,存储起来,然后还是按照原来的算法生成唯一短字符串,只是当随机到这些靓号的时候,重新生成,也就是要多查一次而已。

相对的,可以把非靓号存储起来,生成的时候从非靓号里取,这样避免了一次查询,这个方案的关键就是非靓号的存储,非靓号可比靓号数目大得多,使用redis还是rds需要权衡一下。(如果使用redis,可以使用set这个数据结构,使用spop进行处理)

重要的话说三遍都不为过。

永远不要动老接口,无论这个接口是别人写的,还是你写的。
永远不要动老接口,无论这个接口有人用,还是没人用。
永远不要动老接口,无论是什么样的理由。

可能要动这个接口的理由很多:

  1. 这个接口代码写的太烂,要优化一下
  2. 这个接口现在没人用了,注释掉或删了吧
  3. 底层实现修改了,这个接口的参数或返回值也要修改
  4. ……

亦或是你自己对自己的修改信心满满:

  1. 我知道哪些地方调用了这个接口,不会有任何影响
  2. 我只是稍微优化了下代码逻辑,保证接口行为同原来一致
  3. ……

真的,有时候连我自己都说服自己要下手了……

- 阅读剩余部分 -

在这一行里,开发一个新的系统或者写一段新的代码,叫做挖坑

这个系统或代码,由后人来维护或修改,叫做填坑

如果说所有的系统和代码,都是坑,未免太过武断,这里面确有宝藏在其中,看过后如醍醐灌顶,大呼过瘾。

不过要说,绝大部分,或者说大部分,都是坑,大家可能都心里默默点头。

挖坑者可能并不是有心挖坑,但是填坑者却要小心填坑

所以写出这么一个填坑要诀,供大家参考。

(以上为本人不靠谱推测,不负任何法律责任)

我这篇博文,是不是也算是给自己挖坑

今天,发现hystrix监控的hystrix-dashboard里没有数据,这个hystrix-dashboard监控的是turbine聚合过的turbine.stream。

一开始怀疑是turbine使用的上游hystrix.stream没有数据,我手动获取hystrix.stream:

curl http://demo.com/hystrix.stream

发现是有数据的。
然后我看日志也没有发现什么异常。就把com.netflix的日志级别调整成debug看下:

java -jar -Dlogging.level.com.netflix=DEBUG hystrix-dashboard.jar

发现是获取到了上游的hystrix的host,全部状态为up,没有问题。

但是日志一直有这个提示:

Skipping event to catch up to end of feed and reduce latency

跳过了事件,以此来追上stream和减少延迟。

为啥要跳过事件,看下代码

com.netflix.turbine.monitor.instance
currentTime = System.currentTimeMillis();
if (skipLineLogic.get() && currentTime < skipProcessingUntil) {
    if (logger.isDebugEnabled()) {
        logger.debug("Skipping event to catch up to end of feed and reduce latency");
    }
} else {
    line = line.trim();
    if (line.length() != 0) {
        break;
    }
}

原来处理从上游获取的stream时,会比较stream里的时间戳和本地时间戳,发现延迟超过指定延迟时间就抛弃该事件。

延迟时间可配置:

turbine.InstanceMonitor.eventStream.skipLineLogic.latencyThreshold

默认为2500毫秒。

于是,我看了下这台服务器的时间:

date

发现比上游hystrix.stream的服务器快了10秒,于是就找运维同时更新了ntp,果然就没有问题了。