思有所皈,绪有所依

给万千思绪,寻一寄存之所

PaaS - Platform as a Service,平台即服务
Baas - Backend as a Service,后端即服务
Serverless - 无服务

都是试图简化后端的复杂性和运维压力

Firebase是谷歌的一项服务,主要针对App开发,提供了通用的一些服务端功能,基本上一个App前端可以不依赖后端就可以开发一款应用。
Supabase是对标Firebase的开源实现。

Supabase目前来看,只适合负载比较小的应用,也就是一个Docker部署可以支撑的情况。这可能只是笔者的误解,看官方的文档时可以部署在Kubernates上,k8s是可以缩放的。但是k8s本身很复杂很重,基本上对个人开发者或者中小企业来说,只能是用云提供商的服务,这就没什么成本优势了。再说Supabase是基于PostgreSQL来提供一些核心能力,就笔者自己的经验来说,数据库用云服务商提供的最省事也最便宜,不然你需要购买CPU、内存和存储,也需要专业的人员来运维,后患很大。

参考:
Supabase

2022年Firebase十大替代平台

APISIX和KONG都是基于OpenResty开发的API网关,从目前看到的资料来看,APISIX的性能要好一些。

OpenResty在nginx上增加动态脚本能力(Lua),主要是解决了nginx修改配置后必须reload的问题。这个耗时以秒计,而OpenResty是动态脚本,耗时就是一次admin api 请求,几毫秒。看官方的文档,一直在强调“同步非阻塞”,既可以充分利用nginx的非阻塞I/O模型,又能享受同步编程的简便性,也就是代码看上去就是同步执行代码,很好理解和开发,但其实执行是非阻塞的效率很高。同步非阻塞的开发体验应该是优于node.js的,只是javascript更流行。事实上nginx也被OpenResty启发,尝试在nginx上增加javascript来实现OpenResty类似的能力,但也没火起来。
参考:OpenResty的现状、趋势、使用及学习方法
参考:从openresty谈到rust

我按APISIX官方的文档用docker-compose的方式进行了简单尝试,发现APISIX还是非常重的,如果在API管理上没有很强的需求,没有必要使用APISIX。个人的体会,需要借助OpenResty的动态配置能力来实现业务的场景,才需要使用OpenResty或者更强(更复杂)的APISIX和KONG。

TODO: OpenResty值得研究一下

官方文档

随机查询

用随机函数的值来排序,以达到随机查询的目的;最好限制一个取数范围,不然对行数比较多的表来说,随机取数查询可能耗时会比较长。

PostgreSQL
select * fro some_table order by random() limit 100;
解决JPA不支持PostgreSQL双冒号的问题

冒号在JPA中是特殊符号,所以需要加转义字符

PostgreSQL
select * from some_table where details::varchar like 'ABC%';

Java中添加转义字符:

Java
String strSql = "select * from some_table where details\\:\\:varchar like 'ABC%'";
长事务的查询与中断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查询
SELECT
pid,
datname AS db,
query_start AS start,
now() - query_start AS lap,
query
FROM pg_stat_activity
WHERE state <> 'idle' and query not like '%pg_stat_activity%'
and (now() - query_start) > interval '10 seconds';

# 取消(pid为前面查询的具体值)
select pg_cancel_backend($pid);

# 中断
select pg_terminate_backend($pid);

PostgreSQL支持全文检索,但是中文的全文检索需要安装zhparser插件。阿里云上购买的PostgreSQL,某些版本不支持,升级到14最新的小版本,或者15才支持。

阅读全文 »

表的大小如果超过了物理内存就应该分区了,分区有两种方式:

  1. 新建表可以在建表的时候指定分区字段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE measurement (
    city_id int not null,
    logdate date not null,
    peaktemp int,
    unitsales int
    ) PARTITION BY RANGE (logdate);

    CREATE TABLE measurement_y2006m02 PARTITION OF measurement
    FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
  2. 对现有表使用继承和创建触发器的方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    CREATE TABLE measurement (
    city_id int not null,
    logdate date not null,
    peaktemp int,
    unitsales int
    );

    CREATE TABLE measurement_y2006m02 (
    CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' )
    ) INHERITS (measurement);

    CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate);

    CREATE OR REPLACE FUNCTION measurement_insert_trigger()
    RETURNS TRIGGER AS $$
    BEGIN
    IF ( NEW.logdate >= DATE '2006-02-01' AND
    NEW.logdate < DATE '2006-03-01' ) THEN
    INSERT INTO measurement_y2006m02 VALUES (NEW.*);
    ELSIF ( NEW.logdate >= DATE '2006-03-01' AND
    NEW.logdate < DATE '2006-04-01' ) THEN
    INSERT INTO measurement_y2006m03 VALUES (NEW.*);
    ...
    ELSIF ( NEW.logdate >= DATE '2008-01-01' AND
    NEW.logdate < DATE '2008-02-01' ) THEN
    INSERT INTO measurement_y2008m01 VALUES (NEW.*);
    ELSE
    RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!';
    END IF;
    RETURN NULL;
    END;
    $$
    LANGUAGE plpgsql;

决定要搭一个自己的博客,是受了《程序员的思维训练:开发认知潜能的九堂课》的启发,External support is part of your mind(大脑之外的思维工具,也会成为你思维头脑的一部分)。

阅读全文 »
0%