全栈开发

介绍

以前工作中有过前端的开发经验,使用后端模版Smarty(主要是外部需求,现在新项目中应该很少使用这个了),前端模版Mustache,页面中使用 js jquery交互逻辑,直接服用一些开源的UI组件Bootstrap,开源的后台UI系统,主要是建设内部后台的时候使用,自动生成CRUD页面;前端的技术栈更新迭代相对后端快些,通过以全栈技术栈为切入点,通过一个简单的系统,学习下最新技术栈工具,主要目的如下:

根据需求,实现一个简单功能的购物系统,目的是为了学习ts->js on node.js全栈开发,了解整体开发构建工具,熟悉下工具开发流程,主要还是了解前端框架工具的使用,以及熟悉通过js运行时环境运行在后端服务上的应用开发工具,以便在后续开发后台系统的时候可以熟练使用这些技术进行开发,这些工具的设计思想可以借鉴到其他后端业务开发语言中。

CRDT

介绍

无冲突复制数据类型(CRDT: conflict-free replicated data type) 是一种简化分布式数据存储系统和多用户应用程序的数据结构。

在许多系统中,某些数据的副本需要存储在多台计算机上。此类系统的示例包括:

  • 在本地设备上存储数据,并且需要将该数据同步到属于同一用户的其他设备(同一用户多端设备同步,例如日历、笔记、联系人或提醒)的移动应用程序;
  • 分布式数据库,维护数据的多个副本(在同一数据中心或不同位置,一般是不同数据中心的多活场景),以便在某些副本离线时系统继续正常工作;
  • 协作软件,例如 Google Docs、Trello、Figma 或许多其他软件,其中多个用户可以同时更改同一文件或数据;
  • 边缘计算场景,比如多个手机/车载app 在无信号的森林中,产生的本地离线协同数据,多个设备同步到云上处理;
  • 大规模数据存储和处理系统,复制数据以实现全球可扩展性。

pool

介绍

平常想到不浪费资源的方法,是对资源进行复用,减少资源消耗和浪费(小时候大人经常在吃饭时说的那句话);在计算机工程领域,存在大量消耗资源的场景,多路复用和池化是最常用的性能优化手段;多路复用存在系统调用,由系统内核层面去支持优化(I/O多路复用select/poll/epoll/kqueue),而池化可以应用用户使用层面来优化;池化(pool)是一种资源复用优化技术,减少资源回收处理,提高资源利用率,资源最好是固定大小,如果在复用资源过程中,资源在逐渐增大,一直复用,也会导致资源消耗过多,到了一定大小之后,通过系统释放掉;在程序启动的时候提前申请加载好资源放到池子中,运行时根据不同的调度管理资源策略从池子中获取准备好的资源,或者运行时新建资源放入池子中,用户程序中进行自定义处理操作,操作完之后将资源重新放入池子中复用,有些资源可以动态扩缩; 资源主要是程序运行时对象,当然这些操作资源实际都是分配在虚拟内存空间的内核空间和用户空间中,比如,进程(process PCB 内核态)、线程(thread TCB 内核态)、协程(coroutine 用户态协作式调度,尽量减少内核调度)为载体的工作任务(work task 在用户态分配栈空间);内存对象(heap object),长链接(tcp connect) 等;主要对这些资源对象进行池化技术进行介绍,了解池化对应场景。

WAL

序言

​ 数据落地之前,如果出现持久化存储引擎实例重启,或者服务当机重启,如何进行故障恢复(Crash Recovery)呢?数据写操作增删改,这些操作状态数据,是如何保证事务中原子性和持久性的呢? 这些问题数据大拿们提出了Algorithms for Recovery and Isolation Exploiting Semantics ,基于语义的恢复与隔离算法,现代数据库的基础理论;当前主流关系型数据在事务实现上都受到该理论的影响,其中有两种故障恢复的方法: 预写日志(write-ahead logging (WAL) ) 和shadow-page technique;shadow-page 方法简单介绍就是每次事务操作,以page为单位,写时复制的方式,分为Current和Shadow,类似主备的形式,如果commit成功,Current中的page合并到 Shadow中; 如果abort不成功丢弃Current的page; 如果Crash了,从Shadow中的page恢复,对所有未提交事务的回滚操作; 由于shadow-page技术的实现以page为单位,page内无法并发操作,commit/回滚时会有大量垃圾回收操作;本文主要介绍WAL,以及对应持久化存储引擎的实现机制介绍。

设计-配置平台

介绍

业务服务在启动时加载配置,配置分为静态配置和动态配置,静态配置如服务监听的端口,日志路径,访问依赖服务单元不同云(region / zone) 域名地址等;动态配置包括业务配置,流程管理配置,策略配置等;静态配置服务启动之后不会更改,而动态配置在服务启动运行时可以动态热加载;将配置的内容和版本进行分离,关注配置的管理而无需关注配置的内容,配置内容用户可以自定义配置内容,使用json-schema进行校验,提供自定义配置内容json给后台ui前端进行单个整体配置的交互,配置后台只需加载json-schema进行校验提交内容,json-schema由用户上传提供地址即可。

工具盒子-ping/traceroute

序言

在访问网络是否ok, 通常喜欢用ping 命令来访问ping www.baidu.com 看是否出现超时;ping在不同的操作系统平台实现方式差不多,底层都是用ICMP协议,每次发ICMP ECHO_REQUEST packet (IP地址/Host, ttl,icmp_seq序列号,RTD/RTT(往返延时)记录 ), 运行结束后统计每个RTT, 最大RTT, 最小RTT, 平均RTT, 标准偏差RTT, 发送/接受packets总数,丢包率 等数据,ping工具在PING(8)中的定义如下:

The ping utility uses the ICMP protocol’s mandatory ECHO_REQUEST datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway. ECHO_REQUEST datagrams (“pings'') have an IP and ICMP header, followed by a “struct timeval'' and then an arbitrary number of “pad” bytes used to fill out the packet.

缓存淘汰策略-LRU

序言

​ 在计算机硬件中缓/内存设计是用来机器启动的时候加载程序,分配运行空间数据,停机,缓/内存中的数据会丢失;磁盘用来持久化存储,提供数据加载到内存中,内存的读写速度比磁盘快很多,以下是Jeff DeanNumbers Everyone Should Know” 中提供的数据(虽然过去10多年了), 读取1MB数据,从内存中读比从磁盘中读取快100+倍;但是缓/内存的空间比磁盘空间少,为了加快数据的访问,减少缓存/磁盘io,大概分为三种:1. 可以提前将数据从磁盘加载到内/缓存中(page)、2. 内/缓存miss从下层存储获取数据(cache,pool,page)、3. 无需加载,直接内/缓存evict;如果提供给进程的最大内/缓存资源到了最大限制,需要对存储资源进行evict操作,常用的evict策略可以从Cache_replacement_policies中了解;有关特定于分页的详细算法,请参阅页面替换算法;有关特定于 CPU 和 RAM 之间缓存的详细算法,请参阅CPU 缓存。这里主要关注LRU evict相关策略。