使用 Quartz 调度器遇到的一些问题

最近,线上运行的定时任务出现调度失败。调整了相关参数后,虽然遏制了调度失败的情况,却导致任务调度的延迟极度增加。同时还观察到,在多机部署的环境中,负载极不均匀,于是深入代码排查一番。

TL; DR

  1. 不要使用 Spring 提供的 org.springframework.scheduling.quartz.SchedulerFactoryBean#setTaskExecutor 方法自定义工作线程池
  2. 要注意 Spring 与 Quartz 的部分配置默认值不一致,如 org.quartz.threadPool.class
  3. 一般情况下使用 Quartz 提供的 SimpleThreadPool 配合参数 org.quartz.threadPool.threadCount 调整最大线程数即可
  4. 如果需要自定义工作线程池,则必须直接实现 org.quartz.spi.ThreadPool 接口,并一定要实现 (更多…)

飞常准 ads-b 脚本分析

最近玩 SDR,看到 ads-b 比较有意思,可以使用树莓派追踪附近飞机的实时位置,还有一些平台可以共享数据,看到更多的飞机。不过由于国内的相关规定,向境外平台分享数据是违法的,所以准本研究研究咱们自己的平台 – 飞常准。

飞常准 ads-b 平台的链接是 https://flightadsb.variflight.com/,页面整体来说跟国外知名的数据分享平台大同小异,不做过多介绍。不过在尝试接入该平台的时候,发现了一些有意思的东西,在此记录一下。

为避免飞常准修改相关页面,将当前官方页面截图记录:

可以看到,文档本身就是修改了一下树莓派的源,然后克隆了一个 github 仓库,运行了安装脚本。接下来我们看看这个仓库的脚本都有什么。该仓库已妥善备份。

https://github.com/davy12315/adsb

安装脚本分析

首先看 setup.sh,没有什么特殊的,就是处理了一下 (更多…)

jOOQ 与 Spring 的一些注意事项

jOOQ 全称 Java Object Oriented Querying,即面向 Java 对象查询。它是 Data Geekery 公司研发的 DA 方案 (Data Access Layer),是一个 ORM 框架。

使用 jOOQ,既不像 Hibernate 等框架封装过高,无法触及 SQL 底层;也不像 MyBatis 等,配置太过繁琐。同时还是 Type Safe 的框架,编译时即可最大程度的发现问题。

不过在 jOOQ 配合 String Cloud 使用的时候,还是踩了几个小坑,特别说明一下。随时补充新遇到的问题。

一、事物问题

jOOQ 默认有一套自己的流式 API,来支持事物。不过,在 Spring 里面,我们使用的最多的还是 @EnableTransactionManagement@Transactional 注解。使用这二者可以开启 Spring (更多…)

记一则由于整数溢出导致的教科书级的死循环

首先铺垫一下,这段代码的输出是什么?

public static void main(String []args){
    System.out.println(Integer.MAX_VALUE + 1);
}

很多人可能很快就能答出来,正确答案是:-2147483648

那么接下来看这段代码:

public static void main(String []args){
    Long total = Long.MAX_VALUE;
    for (int i = 0; i < total; i++) {
        System.out.println(i);
    }
}

乍看之下似乎没啥大毛病,但是结合前面的铺垫,就会发现:

当 i 增长到 Integer.MAX_VALUE  的时候,“奇迹”出现了。接下来,下一个 i 值变为了 -2147483648。跟 (更多…)

MyBatis 获取自增 ID 的小坑

在 MyBatis 中,获取自增 ID 主要有两个方法:

  1. 在 SQL 中增加两个属性,useGeneratedKeys  和 keyProperty
  2. 增加 selectKey  语句块,执行自定义 SQL 获取自增 ID

针对这几种方法,有几个小问题需要注意:

  1. useGeneratedKeys  是基于 JDBC 的 Prepared Statement  实现的,具体做法是调用 JDBC 的 getGeneratedKeys  方法,在 Prepared Statement  对象中取相应的值。当 DB 为 MySQL 的时候,会在响应时返回相应的自增字段值。但是,在某些实现 DB 分库分表的 Proxy 中,由于涉及 SQL 转换、重写的问题,可能对 Prepared Statement  的支持并不完整,导致 useGeneratedKeys  选项无法正常返回对应的自增 (更多…)

记一次 JNI 导致 Java fd 泄露的排查过程

前几天接到反馈,线上某机器上的服务在进行后端调用的时候失败了。查看日志是端口分配失败。通过 netstat -nulp  看到大量端口占用,用户段端口49152 到 65535 全部被占满。于是通过 awk sort 和 uniq 统计出每个进程的端口占用情况,发现某些 Java 服务占用了 2w+ 端口,于是对该服务展开分析。

首先考虑的是应用有大量 Socket 对象没有关闭释放,于是将堆 dump 出来,使用 VisualVM 加载分析。由于泄露的是 UDP 端口,于是考虑查找 Java 中 UDP socket 对应的对象 DatagramSocket 。可是一顿操作之后发现堆中并不存在该类对象,倒是找到了几个 DatagramSocketAdaptor  对象。查看了框架发现使用了 Netty 做 NIO,因此实际使用的是 NioDatagramChannel 和 DatagramSocketAdaptor (更多…)

MySQL 分区表的一些问题

最近在使用 MySQL 分区表的时候,研究了一下多列 Range 分区,也就是

PARTITION BY RANGE COLUMNS(`a`, `b`, `c`) (
    PARTITION p1 VALUES LESS THAN (0, 0, MAXVALUE),
    PARTITION p2 VALUES LESS THAN (10, 10, MAXVALUE),
    PARTITION p3 VALUES LESS THAN (20, 20, MAXVALUE)
)

在多列的情况下,MySQL 的分区策略和单列略有不同,这也是比较坑的地方,查遍所有文档都没人提到。。。

先说说单列 Range 分区。比如,如果这么写:

PARTITION BY RANGE(`a`) (
    PARTITION p1 VALUES LESS THAN (0),
  (更多…)

Apache HttpClient 使用代理服务器 Proxy 的一个小坑

今天在调试一个用 HttpClient 写的 Demo 的时候遇到了一个问题:

org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (org.apache.http.conn.UnsupportedSchemeException) caught when processing request to {tls}->http://proxyserver:port->https://servername:443: http protocol is not supported

也就是在通过 HTTP Proxy 进行 HTTPS 连接的时候,HttpClient 报了一个不支持 HTTP 协议。查了一下发现问题在于我使用 HttpClient 的方法。

由于我在使用 HttpClient 的时候是手动创建的 Registry ,而在创建的时候没有注册 (更多…)

MySQL 隐式转化整理

前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下。希望对大家有所帮助。

当我们对不同类型的值进行比较的时候,为了使得这些数值「可比较」(也可以称为类型的兼容性),MySQL会做一些隐式转化(Implicit type conversion)。比如下面的例子:

mysql> SELECT 1+'1';
        -> 2
mysql> SELECT CONCAT(2,' test');
        -> '2 test'

很明显,上面的SQL语句的执行过程中就出现了隐式转化。并且从结果们可以判断出,第一条SQL中,将字符串的“1”转换为数字1,而在第二条的SQL中,将数字2转换为字符串“2”。

MySQL也提供了CAST()函数。我们可以使用它明确的把数值转换为字符串。当使用CONCA()函数的时候,也可能会出现隐式转化,因为它希望的参数为字符串形式,但是如果我们传递的不是字符串呢:

mysql> (更多…)

利用API揪出抢占Win8窗口焦点的熊孩纸

起因:谁在抢镜头?!

为了开始Windows Phone 8的开发,这两天将系统升级到了Windows8.1,安装倒是又快又方便的,解压ISO镜像双击Setup一路下一步(嘛其实还输了密钥之类的)就安装好了~
不过不知道为什么去年买的正版密钥激活不了了,于是按照指示拨打了微软的客服电话,客服妹纸问了几个问题就给激活了~然后花了两三个小时进行各种配置美化和常用软件安装,看起来好极了~

01

可耻的晒桌面(其实和之前用Win7时没啥区别……已经一年多没换过主题了……)

刚开始用着感觉没啥问题啊,速度也挺快,可是打开VS写了几行代码就发现有些不对劲了,智能感应总是会莫名其妙的半路消失,然后发现聊QQ时经常打一半字输入法不见了,更糟糕的是逛B站全屏视频时会时不时跳出到窗口模式……根据十几年(啊天哪我怎么这么老了= -)的视窗操作系统(其实就是Windows~听起来逼格高那么一点?)使用经验,首先想到的是焦点被抢占了~之后用一般窗口程序观察了一下,发现的确是这样,时不时就会失去焦点半秒然后再恢复,网上查了一下,大多数说是支付宝安全控件之类的,可是我貌似不是因为这个引起的……那么究竟是谁干的呢?

04

经过:捕捉熊孩子,我有特殊的技巧

作为半个程序猿,当然就要用程序猿的方式解决咯(事实上是因为我找不到其它方法……),很久很久以前就知道了Windows有提供获得焦点窗口句柄(handle,话说为什么要翻译成“句柄”这种不明所以的东西? (更多…)