在 PostgreSQL 函数中使用可选条件
为了说明问题我创建了一张员工表 employees 并初始化了一些数据
1 | CREATE TABLE employees |
为了说明问题我创建了一张员工表 employees 并初始化了一些数据
1 | CREATE TABLE employees |
最近读到一篇非常好的文章 PostgreSQL 中 timestamp 与 timestamptz 的区别,也可以访问 https://japinli.github.io/2023/03/postgresql-timestamp/,读完这篇文章后学习到了两点
EXTRACT(EPOCH FROM source) 是基于 Unix 纪元的结果。src/backend/utils/adt/timestamp.c 文件中的 timestamp_in 和 timestamp_out 函数,从源码上理解时间字符串的输入和输出逻辑。因此本文的逻辑是基于显示的结果而言,从显示的结果推论可能的原因,只是为了方便理解。推荐阅读它而不是本文。
在我们的业务中有一个生产者程序不停地向 message 表写入记录,简化的 message 表的结构如下所示
1 | CREATE TABLE message |
另外有一个消费者程序不停地读取 message 表的数据,这个消费者程序依赖一个称为“水位线”的时间戳,所有创建时间小于等于水位线的消息都已经处理,我们使用 consumer 表来记录当前的水位线
1 | CREATE TABLE consumer |
我们会有一个定时任务每隔一段时间调度一次消费者程序,消费者程序的主要逻辑是
检查当前水位线
1 | test=# SELECT watermark FROM consumer; |
使用当前水位线加载待处理消息
1 | test=# SELECT content, create_time FROM message WHERE create_time > '2024-04-30 15:16:17+08' AND create_time <= NOW() ORDER BY create_time; |
逐条处理消息,并用当前消息的创建时间更新水位线,最后一条消息处理完成时
1 | test=# UPDATE consumer SET watermark = '2024-04-30 17:18:19.956867+08'; |
就当前的 SQL 版本模拟的逻辑而言在定时任务第 2 轮调度时将没有待处理消息。但是当我们使用 Java 语言实现上面的逻辑时我们发现在定时任务第 2 轮调度时内容为 bbb 的消息会再一次被处理。在 Java 版本的实现里我们使用了 java.util.Date 类型来表示 create_time 和 watermark。
假设有一个 PDI(Kettle)Job,运行这个 Job 需要耗时 30 秒钟。现在每 10 秒钟调度运行一次这个 Job。我们的问题是这个 Job 的运行情况是怎样的?具体地说是上一个调度的 Job 还没有执行完就到了下一个调度的 Job 的执行时间,那么下一个调度的 Job 会执行吗?也就是定时任务如果执行的时间很长的话,那么下一次还能按时执行嘛?
Kettle 的定时任务是哪一种情况呢?
在 PostgreSQL 中执行如下的 SQL 语句
1 | SELECT 'AND c1 = ''' || 5 || ''''; |
将输出 AND c1 = '5'。我们的疑问是 5 两边的单引号 ' 是怎么得到的?
通过前面几篇文章我们已经实现了将网关作为资源服务器并在网关实现认证和授权,其他服务将是一个纯粹的微服务,那么我们将问一个问题其他微服务如何获取到已授权用户的用户信息?
我们将要实现这样一个微服务系统,将 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,均需要向服务注册中心注册自己。