分类
Java 笔记 编程

DataSource health check failed

在项目中集成ShardingJDBC,启动报错:ConnectionCallback; isValid; nested exception is java.sql.SQLFeatureNotSupportedException: isValid

该项目是新做的,使用较新版本的Spring Boot 2.3,数据库连接词用Hikari。

用Sharding-JDBC蛮久了,之前一直是与DBCP2或Druid,没出过什么问题。这次集成Hikari,系统虽然报错但也能正常启动,仔细看源码,问题应该出在键康检查。

分类
Java

Java基于Runtime调用外部程序出现阻塞的解决

有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf、ffmpeg来转换视频等。如果你的代码这样写:

Runtime.getRuntime().exec(command),会发现程序一下就执行完毕,而在命令行里要执行一会,是因为java没有等待外部程序的执行完毕,此时就需要使用阻塞,来等待外部程序执行结果:

InputStream stderr = process.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr, "GBK");
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
  System.out.println(line);
int exitValue = process.waitFor();

对于一般的外部程序使用上面的阻塞代码就可以,至少pdf2swf.exe是没有问题的。

但是紧接着又发现对于ffmpeg来说,以上代码会让程序卡住不动,需要使用另一种方式,封装成了一个方法,如下:

分类
Java 笔记

阿里云自动动态地址解析

家里找电信开通了动态公网地址,每天IP会变一次。我的域名是在阿里云申请的,路由器只支持花生壳和公云的DDNS设置,每天手动变更一次域名指向麻烦,利用阿里云的API,写了一个动态更新的小工具。

首先在阿里云后台申请创建AccessKey:

分类
Java 日记 笔记

Sharding JDBC Demo 2.0 (主从版)

从今年初接触Sharding JDBC 4.0到现在,近一年了,用来做日志和消息分表一直运行,没什么大的问题。前些天生产新上了一个服务,是因为Sharding JDBC把select for update语句解析为查询,在从库中执行,因为从库是只读权限所以报错。

之前没在测试环境发现这个问题,是因为测试环境数据库没有主从。想起当时刚接触Sharding JDBC写的Demo,于是整理一番,重新拉分支,并完善整个流程,模拟真实场景。

分类
Java

Spring 框架的设计理念与设计模式分析

Spring 的骨骼架构

Spring 总共有十几个组件,但是真正核心的组件只有几个,下面是 Spring 框架的总体架构图:

图 1 .Spring 框架的总体架构图

从上图中可以看出 Spring 框架中的核心组件只有三个:Core、Context 和 Beans。它们构建起了整个 Spring 的骨骼架构。没有它们就不可能有 AOP、Web 等上层的特性功能。下面也将主要从这三个组件入手分析 Spring。

分类
Java 大数据 笔记 编程

Spring Data Elasticsearch兼容问题

使用Spring Data Elasticsearch查询Elasticsearch数据计数

NativeSearchQueryBuilder searchQueryBuilder1 = new NativeSearchQueryBuilder()
                    .withIndices(BURY_POINT_DURATION)
                    .withQuery(boolQueryBuilder)
                    .withFields("eventId", "eventType", "eventName");
SearchQuery searchQuery1 = searchQueryBuilder1.build();
Long clickTotalCount = elasticsearchRestTemplate.count(searchQuery1);

执行错误:Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.elasticsearch.search.SearchHits.getTotalHits()J

分类
大数据

Flink的时间与watermarks详解

当我们在使用Flink的时候,避免不了要和时间(time)、水位线(watermarks)打交道,理解这些概念是开发分布式流处理应用的基础。那么Flink支持哪些时间语义?Flink是如何处理乱序事件的?什么是水位线?水位线是如何生成的?水位线的传播方式是什么?让我们带着这些问题来开始本文的内容。

分类
Java

分布式自增ID算法 – 雪花算法

一般情况,实现全局唯一ID,有三种方案,分别是通过中间件方式、UUID、雪花算法。

方案一,通过中间件方式,可以是把数据库或者redis缓存作为媒介,从中间件获取ID。这种呢,优点是可以体现全局的递增趋势(优点只能想到这个),缺点呢,倒是一大堆,比如,依赖中间件,假如中间件挂了,就不能提供服务了;依赖中间件的写入和事务,会影响效率;数据量大了的话,你还得考虑部署集群,考虑走代理。这样的话,感觉问题复杂化了

方案二,通过UUID的方式,java.util.UUID就提供了获取UUID的方法,使用UUID来实现全局唯一ID,优点是操作简单,也能实现全局唯一的效果,缺点呢,就是不能体现全局视野的递增趋势;太长了,UUID是32位,有点浪费;最重要的,是插入的效率低,因为呢,我们使用mysql的话,一般都是B+tree的结构来存储索引,假如是数据库自带的那种主键自增,节点满了,会裂变出新的节点,新节点满了,再去裂变新的节点,这样利用率和效率都很高。而UUID是无序的,会造成中间节点的分裂,也会造成不饱和的节点,插入的效率自然就比较低下了。

方案三,基于redis生成全局id策略,因为Redis是单线的天生保证原子性,可以使用原子性操作INCR和INCRBY来实现,注意在Redis集群情况下,同MySQL一样需要设置不同的增长步长,同时key一定要设置有效期,可以使用Redis集群来获取更高的吞吐量

方案四,通过snowflake算法如下:

SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图:

分类
Java 编程

Spring Data 使用 Redis 自增方法报错

Spring Data Redis 的 RedisTemplate 对 Redis 进行了封装。在对某值调用increment()方法时报错:

redis ERR value is not an integer or out of range

redisTemplate.opsForValue().increment(key);

大家都知道redis序列化是将key,value值先转换为流的形式,再存储到redis中。

RedisTemplate是使用的JdkSerializationRedisSerializer序列化,序列化后的值包含了对象信息,版本号,类信息等,是一串字符串,所以无法进行数值自增操作。

而StringRedisTemplate序列化策略是字符串的值直接转为字节数组,所以存储到redis中是数值,所以可以进行自增操作。

分类
Java

Flink:ElasticsearchSinkFunction is not serializable

用Java把Flink结果数据下沉到Elasticsearch,执行时执出ElasticsearchSinkFunction is not serializable异常:

The implementation of the provided ElasticsearchSinkFunction is not serializable. The object probably contains or references non-serializable fields.