PostgreSQL TIMESTAMP 类型映射为 Java Date 类型时精度丢失问题
问题
在我们的业务中有一个生产者程序不停地向 message 表写入记录,简化的 message 表的结构如下所示
1 | CREATE TABLE message |
另外有一个消费者程序不停地读取 message 表的数据,这个消费者程序依赖一个称为“水位线”的时间戳,所有创建时间小于等于水位线的消息都已经处理,我们使用 consumer 表来记录当前的水位线
1 | CREATE TABLE consumer |
我们会有一个定时任务每隔一段时间调度一次消费者程序,消费者程序的主要逻辑是
检查当前水位线
1
2
3
4
5test=# SELECT watermark FROM consumer;
watermark
------------------------
2024-04-30 15:16:17+08
(1 row)使用当前水位线加载待处理消息
1
2
3
4
5
6test=# SELECT content, create_time FROM message WHERE create_time > '2024-04-30 15:16:17+08' AND create_time <= NOW() ORDER BY create_time;
content | create_time
---------+-------------------------------
aaa | 2024-04-30 16:17:18.936795+08
bbb | 2024-04-30 17:18:19.956867+08
(2 rows)逐条处理消息,并用当前消息的创建时间更新水位线,最后一条消息处理完成时
1
2
3
4
5
6
7test=# UPDATE consumer SET watermark = '2024-04-30 17:18:19.956867+08';
UPDATE 1
test=# SELECT watermark FROM consumer;
watermark
-------------------------------
2024-04-30 17:18:19.956867+08
(1 row)
就当前的 SQL 版本模拟的逻辑而言在定时任务第 2 轮调度时将没有待处理消息。但是当我们使用 Java 语言实现上面的逻辑时我们发现在定时任务第 2 轮调度时内容为 bbb 的消息会再一次被处理。在 Java 版本的实现里我们使用了 java.util.Date 类型来表示 create_time 和 watermark。
PDI 定时任务调度问题
问题
假设有一个 PDI(Kettle)Job,运行这个 Job 需要耗时 30 秒钟。现在每 10 秒钟调度运行一次这个 Job。我们的问题是这个 Job 的运行情况是怎样的?具体地说是上一个调度的 Job 还没有执行完就到了下一个调度的 Job 的执行时间,那么下一个调度的 Job 会执行吗?也就是定时任务如果执行的时间很长的话,那么下一次还能按时执行嘛?
- Case 1:无论上一次 Job 是否执行完成,下一次 Job 按照 10 秒钟的间隔准时开始;
- Case 2:上一次 Job 未执行完成,下一次 Job 不会开始执行;一旦上一次 Job 执行完成,下一次 Job 立即开始执行,中间没有间隔;
- Case 3:上一次 Job 未执行完成,下一次 Job 不会开始执行;上一次 Job 执行完成后等待 10 秒钟的间隔再开启下一次 Job 的执行;
Kettle 的定时任务是哪一种情况呢?
如何理解 PostgreSQL 中两个邻近的单引号
在 PostgreSQL 中执行如下的 SQL 语句
1 | SELECT 'AND c1 = ''' || 5 || ''''; |
将输出 AND c1 = '5'。我们的疑问是 5 两边的单引号 ' 是怎么得到的?
在网关解析 JWT 并中继给其他服务
通过前面几篇文章我们已经实现了将网关作为资源服务器并在网关实现认证和授权,其他服务将是一个纯粹的微服务,那么我们将问一个问题其他微服务如何获取到已授权用户的用户信息?
将 Spring Cloud Gateway 作为 OAuth2 的资源服务器
我们将要实现这样一个微服务系统,将 Spring Cloud Gateway 作为 OAuth2 的资源服务器,在 Gateway 实现集中的统一的鉴权功能,各个微服务之间的调用不再单独鉴权。系统的规划如下表所示
| 系统 | 端口 | 说明 |
|---|---|---|
| example-auth | 9090 | 认证与授权服务 |
| example-eureka | 8761 | 服务注册中心 |
| example-gateway | 8080 | 服务网关 |
| example-user | 8081 | 用户服务 |
| example-product | 8082 | 商品服务 |
| example-order | 8083 | 订单服务 |
| example-common | - | 公共模块 |
example-auth 是一个独立的服务,它不会向服务注册中心注册自己,其他的服务,包括 example-gateway,均需要向服务注册中心注册自己。
在 Docker 上部署 Spring Cloud 工程
我们有一个使用 Spring Cloud 技术栈开发的简单的商城项目 acomma/shop tag:spring-boot-2,现在要将它构建成 Docker 镜像并以容器的方式运行起来。
Spring Authorization Server 实践
Spring Security OAuth 的生命周期已经结束,现在推荐使用 Spring Authorization Server。
Spring Security OAuth2 实践
Spring Security OAuth 的生命周期已经结束,官方已经删除它的文档,现在推荐使用 Spring Authorization Server,但是还是有很多老项目在继续使用 Spring Security OAuth,学习它仍然是必要的。虽然官方文档已经删除了,但是找到了一篇较早时间的翻译 Spring Security OAuth2 开发指南,可以作为实践的基础。网络上也有很多如何使用它的文章,这篇文章是自己实践的一点记录。