20211029
MyNikko.com 微處理器博物館 - Intel CPU Museumhttps://www.mynikko.com/CPU/index.html
20211021
可以从横向和纵向来看待低代码平台带来的作用。
横向:强调低代码平台的通用性,是否支持所见即所得,是否支持更复杂的模版,是否支持二次开发。面向不同的用户,则需要不同的能力。例如,面向运营同学使用的营销低代码平台,就会更加依赖所见即所得编辑能力和开箱即用的营销活动模版,使得非技术的业务人员也能方便的使用。
低代码平台的持续运营需要依赖标准化。通过抽象组件规范,定制组件交互,实现不同人开发的组件都满足统一的协议。低代码平台通过编排组件,使业务运转起来。
通常,标准化是比较难执行和推广的,随着团队人员更迭,成本往往越来越高。同时,标准化也是反人性的,用条条框框约束人,且没有对错可言,它带来了不自由,不灵活,易引起抵触情绪。只有低代码平台带来降本增效收益能够大于标准化所带来的“烦恼”,标准化才具备广泛推广的价值。
从平台生态的角度考虑,低代码平台需要强管控,把一些质量不高的组件挡在外面,否则一样会影响整个平台的口碑。这里要强调一下,好的管控不是靠人来实现的,而是靠技术手段来实现的。
纵向:强调的是领域内的业务纵深,比如专注于商品或者供应链等业务领域的前端组件。它们本身对其他业务没有帮助,但在其领域内可以带来极高的价值。
抽象领域内的组件往往需要对业务有深入的理解,并且对业务的“变”与“不变”有深入的思考和判断,这样才能做好判断,抽象和沉淀最体现业务本质的组件。
通过 Jenkins Pipeline 与 SonarQube 集成,对代码进行扫描
heap dump 生产 jvm 快照,通过分析快照找到占用内存大的对象,从而找到代码位置。
通过设置-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump
参数来生产快照
20211019
就WINDOWS端的加速原理来说,可以用7个步骤来解释:
- 客户端访问https://github.com
- 客户端向dns查询github.com的ip,FastGithub拦截dns数据包并伪造解析结果为127.0.0.1
- 客户端请求到FastGithub的https://127.0.0.1:443
- FastGithub使用fastgithub.cer颁发服务器证书给客户端
- FastGithub查询和计算github.com最快的ip
- FastGithub与github.com进行无sni的tls连接
- FastGithub将请求反向代理到https://github.com
https://github.com/dotnetcore/FastGithub/https://github.com/dotnetcore/FastGithub/
20211018
Spring 提供的 ResolvableType API,提供了更加简单易用的泛型操作支持
sping激活profile
写测试用例时,可以指定我们使用哪个 Profile:
@ActiveProfiles("remote")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config.xml")
public class ServiceTest {
@Autowired
private UserService userService;
}
业务类
public abstract class UserService extends BaseService<User> { } @Profile("local") @Service public class LocalUserService extends UserService {} @Profile("remote") @Service public class RemoteUserService extends UserService {}
Spring 对 Java8 的时间类型支持
对 jsr310 的支持,只要能发现 java.time.LocalDate,DefaultFormattingConversionService 就会自动注册对 jsr310 的支持,只需要在实体/Bean 上使用 DateTimeFormat 注解:
class Entity{ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime dateTime; @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate date; @DateTimeFormat(pattern = "HH:mm:ss") private LocalTime time;
}
@RequestMapping("/test")
public String test(@ModelAttribute("entity") Entity entity) {
return "test";
}
当前端页面请求:
localhost:9080/spring4/test?dateTime=2013-11-11 11:11:11&date=2013-11-11&time=12:12:12
会自动进行类型转换
另外 spring4 也提供了对 TimeZone 的支持,比如在 springmvc 中注册了 LocaleContextResolver 相应实现的话(如 CookieLocaleResolver),我们就可以使用如下两种方式得到相应的 TimeZone:
RequestContextUtils.getTimeZone(request)
LocaleContextHolder.getTimeZone()
不过目前的缺点是不能像 Local 那样自动的根据当前请求得到相应的 TimeZone,如果需要这种功能需要覆盖相应的如 CookieLocaleResolver 中的如下方法来得到:
protected TimeZone determineDefaultTimeZone(HttpServletRequest request) {
return getDefaultTimeZone();
}
-
另外还提供了 DateTimeContextHolder,其用于线程绑定 DateTimeContext;而 DateTimeContext 提供了如:Chronology、ZoneId、DateTimeFormatter 等上下文数据,如果需要这种上下文信息的话,可以使用这个 API 进行绑定。
-
比如在进行日期格式化时,就会去查找相应的 DateTimeFormatter,因此如果想自定义相应的格式化格式,那么使用 DateTimeContextHolder 绑定即可。
Kafka 生产环境部署指南https://xie.infoq.cn/article/d57f83779490c7ff62b6b59ae
时间轮
一张图理解Kafka时间轮(TimingWheel),看不懂算我输! - 知乎本文是【字节可视化系列】Kafka专栏文章。 通过本文你将了解到时间轮算法思想,层级时间轮,时间轮的升级和降级。 时间轮,是一种实现延迟功能(定时器)的巧妙算法,在Netty,Zookeeper,Kafka等各种框架中,甚至…
https://zhuanlan.zhihu.com/p/121483218
java 核心线程大小与线程池最大大小的区别
1、当提交一个新任务到线程池时首先线程池判断基本线程池(corePoolSize)是否已满?没满,创建一个工作线程来执行任务。满了,则进入下个流程;其次线程池判断工作队列(workQueue)是否已满?没满,则将新提交的任务存储在工作队列里。满了,则进入下个流程;最后线程池判断整个线程池(maximumPoolSize)是否已满?没满,则创建一个新的工作线程来执行任务,满了,则交给饱和策略来处理这个任务;如果线程池中的线程数量大于 corePoolSize 时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过 keepAliveTime,线程也会被终止。
核心线程池的线程在idle的时候不会被终止,其他的线程会终止
2、饱和策略:
Abort策略:默认策略,新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。
CallerRuns策略:为调节机制,既不抛弃任务也不抛出异常,而是将某些任务回退到调用者。不会在线程池的线程中执行新的任务,而是在调用exector的线程中运行新的任务。
Discard策略:新提交的任务被抛弃。
DIscardOld策略:和最老的线程尝试竞争,竞争不过就被抛弃。
20211015
支持完整的SQL语法是一个庞大的工程。在presto中有完整的SqlBase.g4文件,定义了presto支持的所有SQL语法,涵盖了DDL语法和DML语法。该文件体系较为庞大,并不适合学习探究某个具体的细节点。
为了探究SQL解析的过程,理解SQL执行背后的逻辑,在简单地阅读相关资料文档的基础上,我选择自己动手编码实验。为此,定义一个小目标:实现一个SQL解析器。用该解析器实现select field from table语法,从本地的csv数据源中查询指定的字段。
20211014
Apache ftpserver 相关特性
-
100%纯 Java,免费的开源可恢复 FTP 服务器。
-
多平台支持和多线程设计。
-
用户虚拟目录,写入权限,空闲超时和上载/下载带宽限制支持。
-
匿名登录支持。
-
上传和下载文件都是可恢复的。
-
处理 ASCII 和二进制数据传输。
-
支持 IP 限制以禁止 IP。
-
数据库和文件可用于存储用户数据。
-
所有 FTP 消息都是可定制的。
-
隐式/显式 SSL / TLS 支持。
-
MDTM 支持-您的用户可以更改文件的日期时间戳。
-
“模式 Z”支持更快地上传/下载数据。
-
可以轻松添加自定义用户管理器,IP 限制器,记录器。
-
可以添加用户事件通知(Ftplet)。
新的时代和它给的解
大数据处理这个领域本身,正在发生着一些革命性的变化。。。
首先, 当数据库开始变的像message queue,很多数据库比如DyanamoDB,开始提供Change Data Capture把对表的更改变成Data Stream供别的系统使用;另一方方面,message queue开始变的像一个可以持久化数据的数据库,当我们也有了可以从任意点replay的可以长期存储的Stream(kafka),Database和Message queue的概念开始变的模糊。Kafka的出现,直接解决了replayable的数据框架的问题。但它的意义不仅如此。
多数据存储之间的consistency的问题,本质上与分布式数据库的replication问题一致,而分布式数据库的replica可以通过total order broadcast,来广播主节点的WriteAheadLog或者changelog到replica节点,由于total order broadcast保证了所有replica节点收到的message是绝对相同的顺序,那么只要replica节点按照受到message的顺序作出对数据相同的更改,我们就实现了分布式数据库对数据的replication,而WriteAheadLog或changelog本质就是data stream;如果我们把数据库的total order broadcast的这项技术应用到分布式业务系统的设计中去,那么我们就可以解决分布式系统中最难点一个问题:消息时序,而kafka可以说为分布式数据(change)提供了一个logic clock和total order,任何数据生产者只需要把数据输入Kafka,任何Kafka的consumer都保证会以相同的顺序接收同一个partition上的message,同时利用Kafka的replayable特性,数据可以写一次,而重新以任意形式apply在其他存储形式上(cache, elastic search, datawarehouse, keyvalue DB等)。这样,我们就解决了多存储的一致性问题。
更进一步,如果我们在replay message的时候,不是简单的原原本本的照抄replica,而是加入业务逻辑处理,把任何业务逻辑的执行,都看成是从raw data得到的derived data问题,那么把业务逻辑加入到流中,我们就得到了一个经过变化的流,如果我们把这个流写入到一个表里,而这个表又可以产生流(通过类似Change Data Capture这种技术,比如AWS DynamoDB Stream), 而我们又有多个业务processor接收这个新流,经过处理,写入Kafka这种流系统,或者写入可以生成流的table…. 如此循环,我们就得到了一个以Kafka的message index为logical clock的全局eventually consistent的分布式流处理系统。
顺着这个思路,任意一个公司的数据处理系统的本质,都可以看成是一个超大的流处理网络。这个思路把一个分布式数据库维护consistency的各种手段,write ahead log,change log shipment,state replication,materialized view分解开来应用到分布式业务系统的设计里,这就是名为Turn Database Inside Out,Database Unbundled的设计和构架大型分布式企业级应用体系的新思路。
从数据库中来,到数据库中去,从数据流来到数据库中去,从对数据库的更改来,到流或数据库中去。当source,computation和sink全都在云上,我们的业务逻辑本质上就是数据库产生任何变化之后trigger的逻辑,而这就是Streaming processor as a database的思路。
当我们有了replayable的source,自动failover的计算节点(由K8S这种保活), 当我们需要写入的sink也已和我们的整个流框架整合,而使用者只需要提供数据处理逻辑的时候,framework就可以通过插入logical id作为fencing token来最终实现sink的commit的幂等(特别是当所有资源都serverless化由云服务商提供),这就最终使得点到点的exactly once处理成为可能,克服了end2end argument对于中间件的限制(具体限制看这个答案,阿莱克西斯:为什么Akka(Actor模型)在中国不温不火?),因为现在framework不再是中间件了,而是从end2end都由framework本身全权控制,用户的程序只是插入到数据流的计算节点中的一步而已;这个发展,解决了分布式框架usability的本质问题, 而这也从本质上消灭了Lambda Architecture要解决的问题(即用不准确的Streaming提供更早的estimation,而利用稳定consistent的batch处理来fix streaming的不准确问题),因为我们现在也可以用streaming来得到consistent的计算结果了!(其实没有解决,只是我们发现batch和stream本质是一样的,而stream可以做到跟batch至少一样好,这样我们就没必要维护两套系统实现了。Latency和Consistency的trade-off,本质上是liveness和safety的trade-off,FLP impossibility决定了再share nothing的异步环境,safety和liveness不可能同时保证。)
Streaming处理系统其实是batch处理系统的超集,即batch只是固定process/event time window下,利用atWaterMark trigger的数据处理模型而已。所以基本上你可以用这套理论体系来分析目前的几乎”任何分布式数据处理系统“。去思考他们的能力和在各个关键节点所做出的trade-off
本文从流计算的本质出发,推导出了在流处理中实现端到端一致性的通用解法,同时结合通用解法,分析了目前几种主流流计算引擎在一致性上的实现思路。有「财大气粗」型的 Google MillWheel,背靠强大的基础架构用于状态管理;有「心灵手巧」型的 Apache Flink,巧妙地结合了分布式一致性快照和两阶段事务实现一致性;也有「重剑无锋」型的 Apache Kafka Streams,直接将流处理过程事务化,屏蔽复杂的底层逻辑,编程模型和理解成本都更简单(当然也一定程度上限制其使用的场景);也有 「蓬勃发展」中的 Apache Spark (Structured)Streaming,底层的一些实现构想和 Apache Flink 愈加趋同,可以期待它将来能达到类似 Apache Spark 在批处理流域中的地位。
流计算的输入数据是没有边界的,这符合我们传统上对流计算认知。在《System Streaming》一书中,作者提出了一个将流批统一考虑的流计算理论抽象,即,任意的数据的处理都是「流(Stream)」 和「表(Table)」间的互相转换,其中流用来表征运动中的数据,表用来表征静止的数据:
-
流 -> 流:没有聚合操作的数据处理过程;
-
流 -> 表:存在聚合操作的数据处理过程;
-
表 -> 流:触发输出表数据变化的情况;
-
表 -> 表:不存在这样的数据处理逻辑。
20211013
要是消息积累太多,Stream的链表岂不是很长,内容会不会爆掉就是个问题了。xdel指令又不会删除消息,它只是给消息做了个标志位。
Redis自然考虑到了这一点,所以它提供了一个定长Stream功能。在xadd的指令提供一个定长长度maxlen,就可以将老的消息干掉,确保最多不超过指定长度。
//PEL如何避免消息丢失
在客户端消费者读取Stream消息时,Redis服务器将消息回复给客户端的过程中,客户端突然断开了连接,消息就丢失了。
但是PEL里已经保存了发出去的消息ID。待客户端重新连上之后,可以再次收到PEL中的消息ID列表。不过此时xreadgroup的起始消息ID 不能为参数 >,而必须是任意有效的消息ID,一般将参数设为0-0,表示读取所有的PEL消息以及自last_delivered_id之后的新消息。
grpc
gRPC 这项技术真是太棒了,爆赞 - 51CTO.COMhttps://developer.51cto.com/art/202110/685433.htm
20211012
为什么要限流
日常生活中,有哪些需要限流的地方?
为什么要限流呢?假如景区能容纳一万人,现在进去了三万人,势必摩肩接踵,整不好还会有事故发生,这样的结果就是所有人的体验都不好,如果发生了事故景区可能还要关闭,导致对外不可用,这样的后果就是所有人都觉得体验糟糕透了。
回到网络上,同样也是这个道理,例如某某明星公布了恋情,访问从平时的50万增加到了500万,系统最多可以支撑200万访问,那么就要执行限流规则,保证是一个可用的状态,不至于服务器崩溃导致所有请求不可用。
如果这时候有特殊情况,比如有些赶时间的志愿者啦、或者高三要高考啦,这种情况就是突发情况,如果也用漏桶算法那也得慢慢排队,这也就没有解决我们的需求,对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。
令牌桶好处就是,如果某一瞬间访问量剧增或者有突发情况,可以通过改变桶中令牌数量来改变连接数,就好比那个食堂排队吃饭的问题,如果现在不是直接去窗口排队,而是先来楼外拿饭票然后再去排队,那么有高三的学生时可以将增加饭票数量或者优先将令牌给高三的学生,这样比漏桶算法更加灵活。
限流思路
对系统服务进行限流,一般有如下几个模式:
熔断
系统在设计之初就把熔断措施考虑进去。当系统出现问题时,如果短时间内无法修复,系统要自动做出判断,开启熔断开关,拒绝流量访问,避免大流量对后端的过载请求。
系统也应该能够动态监测后端程序的修复情况,当程序已恢复稳定时,可以关闭熔断开关,恢复正常服务。常见的熔断组件有Hystrix以及阿里的Sentinel,两种互有优缺点,可以根据业务的实际情况进行选择。
服务降级
将系统的所有功能服务进行一个分级,当系统出现问题需要紧急限流时,可将不是那么重要的功能进行降级处理,停止服务,这样可以释放出更多的资源供给核心功能的去用。
例如在电商平台中,如果突发流量激增,可临时将商品评论、积分等非核心功能进行降级,停止这些服务,释放出机器和CPU等资源来保障用户正常下单,而这些降级的功能服务可以等整个系统恢复正常后,再来启动,进行补单/补偿处理。除了功能降级以外,还可以采用不直接操作数据库,而全部读缓存、写缓存的方式作为临时降级方案。
延迟处理
这个模式需要在系统的前端设置一个流量缓冲池,将所有的请求全部缓冲进这个池子,不立即处理。然后后端真正的业务处理程序从这个池子中取出请求依次处理,常见的可以用队列模式来实现。这就相当于用异步的方式去减少了后端的处理压力,但是当流量较大时,后端的处理能力有限,缓冲池里的请求可能处理不及时,会有一定程度延迟。后面具体的漏桶算法以及令牌桶算法就是这个思路。
特权处理
这个模式需要将用户进行分类,通过预设的分类,让系统优先处理需要高保障的用户群体,其它用户群的请求就会延迟处理或者直接不处理。
缓存、降级、限流区别
- 缓存是用来增加系统吞吐量,提升访问速度提供高并发。
- 降级是在系统某些服务组件不可用的时候、流量暴增、资源耗尽等情况下,暂时屏蔽掉出问题的服务,继续提供降级服务,给用户尽可能的友好提示,返回兜底数据,不会影响整体业务流程,待问题解决再重新上线服务
- 限流是指在使用缓存和降级无效的场景。比如当达到阈值后限制接口调用频率,访问次数,库存个数等,在出现服务不可用之前,提前把服务降级。只服务好一部分用户。
三极管,它就是一种晶体管,特性是从一端通电,另外两端的电流就可以通过,不通电,另外两端的电流就不能通过。
这特性不就是一个开关么?
它和下面这个东西差不多,只不过不需要手动开关,而是通过通电来控制开关。
开和关,就是 1 和 0。计算机世界的组成单元 1 和 0 就是这么实现的。
为什么 Go 语言把类型放在后面?
Go 官方核心思想是:这种声明方式(从左到右的风格)的一个优点是,当类型变得更加复杂时,它的效果非常好(One merit of this left-to-right style is how well it works as the types become more complex)。
Go 的变量名总是在前,在人的代码阅读上可以保持从左到右阅读,不需要像 C 语言一样在一大堆声明中用技巧找变量名对应的类型。
比如以下两个例子:
c语言
int (*(*fp) ( int (*)(int, int), int) ) (int, int)
fp 是个函数指针,该函数指针
第一参数为 int (*)(int, int), 是一个返回int 且有2个int 参数的函数指针
第二个参数为 int
返回值是 一个函数指针 int (*) (int,int)
go语言
fp func(func(int,int) int, int) func(int, int) int
fp是一个函数,该函数参数有两个
第一个是 func(int,int) int 这是一个返回int 类型且参数为 int int 的函数
第二个参数是int
fp 返回值是一个函数 func(int, int) int
怎么快速正确的读取c语言的类型声明?
Clockwise/Spiral Rulehttp://c-faq.com/decl/spiral.anderson.html
20211011
Redis watch命令——监控事务在 Redis 中使用 watch 命令可以决定事务是执行还是回滚。一般而言,可以在 multi 命令之前使用 watch 命令监控某些键值对,然后使用 multi 命令开启事务,执行各类对数据结构进行操作的命http://c.biancheng.net/view/4544.htmlredis watch命令实现秒杀demo - 简书1.思路 在redis提供了incr命令进行递增操作,可以保证原子性。利用watch实现也可以实现递增递减的操作。WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(...https://www.jianshu.com/p/93cd65d07b56
在 Spring 中要使用同一个连接操作 Redis 命令的场景,这个时候我们借助的是 Spring 提供的 SessionCallback 接口Redis的基础事务和常用操作和其他大部分的 NoSQL 不同,Redis 是存在事务的,尽管它没有数据库那么强大,但是它还是很有用的,尤其是在那些需要高并发的网站当中,使用 Redis 读/写数据要比数据库快得多,如果http://c.biancheng.net/view/4540.html
现实中 Redis 执行读/写速度十分快,而系统的瓶颈往往是在网络通信中的延时,为了解决这个问题,可以使用 Redis 的流水线,但是 Redis 的流水线是一种通信协议使用流水线(pipelined)提高Redis的命令性能
20210930
如何改写分页查询?
查询条件放到二级索引子查询中,在子查询列表中中只查询id 这是防止回表的关键
通过二级索引返回的id再和主表关联
select id,name,balance FROM account where id >= (select a.id from account a where a.update_time >= '2020-09-19' limit 100000, 1) LIMIT 10;
Redis HyperLogLog 的应用场景
鉴于 HyperLogLog 不保存数据内容的特性,所以,它只适用于一些特定的场景。我这里给出一个最常遇到的场景需要:计算日活、7日活、月活数据。
分析:如果我们通过解析日志,把 ip 信息(或用户 id)放到集合中,例如:HashSet。如果数量不多则还好,但是假如每天访问的用户有几百万。无疑会占用大量的存储空间。且计算月活时,还需要将一个整月的数据放到一个 Set 中,这随时可能导致我们的程序 OOM。
20210923
这才是 Redis 分布式锁的正确实现方式https://mp.weixin.qq.com/s/cdmwI-H9NUHUQNvr_6DQgQ
20210917
redis 实现布隆过滤器
一个简单的 JS 库,用来使用脚本进行网页绘图。它基于 Canvas,可以绘制文字、矩形、圆形、图片、HTML 片段和 SVG 文件iDraw Playgroundhttps://idraw.js.org/playground/?demo=elem-html
利用redis zset 来实现超时
面试官:说出订单超时取消订单的5种实现方案!生成订单30分钟未支付,则自动取消,该怎么实现?https://mp.weixin.qq.com/s/0EUytOr7J-UmSbyQ2SbZQA
20210916
Redis 到底是怎么实现“附近的人”这个功能的呢?http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&mid=2247538725&idx=2&sn=804e5f12e184ee8a92b244b15daf2adf&chksm=9bd3f5bdaca47cab326dbb99581810becd604640802ccd340a1e0cc8c6f37d9135a38add398b&mpshare=1&scene=24&srcid=0804Qtmq2rZgFhw4cKFArYHo&sharer_sharetime=1628053638855&sharer_shareid=3e190772201d8c1259d3e5ee138cea6e#rd 16个Redis常见使用场景总结
http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247510130&idx=2&sn=a88ce0b70f28acb6bf2a29d6b5fe2065&chksm=ebd5975edca21e486ec50959ba8aca07eecabf5550ecb67a5e678c306e2bf1df42d1184329a8&mpshare=1&scene=24&srcid=07270fTZkf7k7OkNIgx7K9s9&sharer_sharetime=1627385272392&sharer_shareid=3e190772201d8c1259d3e5ee138cea6e#rd
Spring Boot 监听 Redis Key 失效事件实现定时任务http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&mid=2247505528&idx=2&sn=e91166a340b15976ef128e84b4baa4de&chksm=9bd37be0aca4f2f6114c1a37a7f6a24fadb5bb779365d655b46fb0ff12e1a63be469491ed2cb&mpshare=1&scene=24&srcid=1023f79bTq50QtANw2WJ0EzE&sharer_sharetime=1603426585487&sharer_shareid=3e190772201d8c1259d3e5ee138cea6e#rd 要想用活Redis,Lua脚本是绕不过去的坎 !【附源码】_Java_程_序_员_51CTO博客要想用活Redis,Lua脚本是绕不过去的坎 !【附源码】,Redis当中提供了许多重要的高级特性,比如发布与订阅,Lua脚本等。Redis当中也提供了自增的原子命令,但是假如我们需要同时执行好几个命令的同时又想让这些命令保持原子性,该怎么办呢?这时候就可以使用本文介绍的Lua脚本来实现。
https://blog.51cto.com/u_15360778/3905326
SOFAChannel#10:分布式事务 Seata 长事务解决方案 Saga 模式详解蚂蚁金服金融科技 - 活动蚂蚁金融科技 数字金融新原力https://tech.antfin.com/community/live/1076
20210914
Hazelcast集群服务(1)——Hazelcast介绍 - 云+社区 - 腾讯云 “分布式”、“集群服务”、“网格式内存数据”、“分布式缓存“、“弹性可伸缩服务”——这些牛逼闪闪的名词拿到哪都是ITer装逼的不二之选。在Javaer的...https://cloud.tencent.com/developer/article/1185863 hazelcast是 一个类似redis的内存数据库
TypeItThe most versatile JavaScript typewriter effect library on the planet.https://typeitjs.com/打字效果的js 类库