Redis常用

基础入门教程

中文官方文档

数据结构常见的应用方式

Redis Strings 字符串

值最大不能超过 512MB

字符串类型对应常用命令

业务不经常变更的数据,接口响应的json字符串等

图片的base64的值

数值秒杀数量之类的,INCR , INCRBYDECR , DECRBY 命令(内部就是同一个命令,只是看上去有点儿不同)会将字符串解析成整数进行原子操作。原子操作意味着多个客户端对同一个key发出INCR命令,也决不会导致竞争的情况。

统计数据,每小时更新访客信息计数器,GETSET可以和INCR一起使用实现支持重置的计数功能

redis> INCR mycounter //访问
(integer) 1
redis> GETSET mycounter "0" //获取并重置计数
"1"
redis> GET mycounter //获取重置后的数据
"0"
redis> 

为减少等待时间,也可以一次存储或获取多个key对应的值,使用MSETMGET命令

> mset a 10 b 20 c 30
OK
> mget a b c //返回由值组成的数组
1) "10"
2) "20"
3) "30"

Redis Hash 哈希

hash (散列) 指令的完整列表

特别适合用于存储对象,Redis 中每个 hash (散列) 可以存储 232 – 1 键值对(40多亿)

系统参数常量配置功能

Redis Lists 列表

list常用命令

简单的消息队列

lpoprpush(或者反过来,lpushrpop)能实现队列的功能,BLPOP,BRPUSH阻塞式实现消息队列。

朋友圈的点赞列表、评论列表、排行榜:lpush命令和lrange命令能实现最新列表的功能,每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表。

限速器,可用于限制某个用户访问某个接口的频率,比如秒杀场景用于防止用户快速点击带来不必要的压力

好友关系,利用集合的一些命令,比如交集、并集、差集等,实现共同好友、共同爱好之类的功能

Redis Set 集合

 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis Sorted Set 有序集合

 string 类型元素的集合,且不允许重复的成员,每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

发布/订阅

Redis 发布订阅简单教程

Pub/Sub发布订阅中文文档

redis实现消息队列(轻量级)的方案

消息队列的考验:Redis有哪些解决方案?

消息队列特征 基于List 基于streams 基于发布订阅
消息保序适用LPUSH/RPOP使用ADD/XREAD
阻塞读取适用BRPOP使用XREAD block
重复消息处理生产者自行实现全局唯一IDStreams自动生成全局唯一ID
消息可靠性适用BRPOP LPUSH使用PENDING List自动留存消息,使用XPENDING查看,使用XACK确认消息
适用场景Redis5.0之前版本的部署环境消息总量少Redis5.0及以后的版本的部署环境消息总量大,需要消费组形式读取数据

缓存使用常见问题

如何保证双写一致性

Cache Aside Pattern 模式

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。

更新的时候,先更新数据库,然后再删除缓存。删除缓存而不更新缓存的原因:有些需要进行复杂计算或查询的缓存场景,更新的操作成本太高。

不一致场景及解决方案

先删除缓存再更新数据库

进行更新操作时,先删除缓存,然后更新数据库,后续的请求再次读取时,会从数据库读取后再将新数据更新到缓存

先更新数据库再删除缓存

进行更新操作时,先更新 MySQL,成功之后,删除缓存,后续读取请求时再将新数据回写缓存。

存在的问题:更新 MySQL 和删除缓存这段时间内,请求读取的还是缓存的旧数据,不过等数据库更新完成,就会恢复一致,影响相对比较小。

异步更新缓存

数据库的更新操作完成后不直接操作缓存,而是把这个操作命令封装成消息扔到消息队列中,然后由 Redis 自己去消费更新数据,消息队列可以保证数据操作顺序一致性,确保缓存系统的数据正常。

Redis 缓存击穿、穿透、雪崩

相关文章和面试问题

Redis必知必会20问

如何保证缓存(redis)与数据库的双写一致性

缓存一致性,缓存穿透,缓存击穿,缓存雪崩解决方案分析

PHP+Redis 有序集合实现 24 小时排行榜实时更新

redis的五种数据结构和应用场景【如微博微信点赞/共同关注/加购物车】

真实项目中应用案例记录

LBS相关应用总结

根据ip获取位置机构信息

geoip

https://github.com/Loyalsoldier/geoip

本项目每周四自动生成 GeoIP 文件,同时提供命令行界面(CLI)供用户自行定制 GeoIP 文件,包括但不限于 V2Ray dat 格式路由规则文件 geoip.dat 和 MaxMind mmdb 格式文件 Country.mmdb

https://github.com/Hackl0us/GeoIP2-CN

小巧精悍、准确、实用 GeoIP2 数据库

https://github.com/maxmind/GeoIP2-php

geoip2 php sdk

https://github.com/Torann/laravel-geoip/tree/master/src

geoip laravel 扩展包

geoip2数据库官方下载地址

相关文章

深入浅出 Symfony2 – 结合 MongoDB 开发 LBS 应用

电子围栏

DIY台式机

计划配置一台和笔记本相同(相近)型号配置的台式机

目前笔记本型号:Vivobook_ASUSLaptop M7600QE

MB (main board):ASUSTeK COMPUTER

制造商: ASUSTeK COMPUTER INC.
产品名称: Vivobook_ASUSLaptop M7600QE_M7600QE
版本: 1.0
序列号: N1N0CX03A800017
UUID: 9299a24f-4296-0d43-9578-44845ede2179
唤醒类型: 电源开关
SKU编号:
系列: Vivobook

句柄 0x0002, DMI类型 2, 15字节
主板信息
制造商: ASUSTeK COMPUTER INC.
产品名称: M7600QE
版本: 1.0
序列号: N101NBCX000766MB
资产标签: ATN12345678901234567

CPU:AMD® Ryzen 9 5900hx with radeon graphics × 16

架构:x86_64
CPU运行模式:32位,64位
地址大小:48位物理地址,48位虚拟地址
字节顺序:小端模式
CPU数量:16
在线CPU列表:0-15
厂商ID:AuthenticAMD
型号名称:AMD Ryzen 9 5900HX with Radeon Graphics
CPU系列:25
型号:80
每核心线程数:2
每个物理核心的核心数:8
插槽数量:1
步进:0
频率增强:已启用
CPU最大频率:4679.2959 MHz
CPU最小频率:1200.0000 MHz
BogoMIPS:6587.45
标志位:fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca fsrm
虚拟化功能:AMD-V
缓存:
L1d缓存:256 KiB(8个实例)
L1i缓存:256 KiB(8个实例)
L2缓存:4 MiB(8个实例)
L3缓存:16 MiB(1个实例)
NUMA(非一致性存储访问):
NUMA节点数:1
NUMA节点0的CPU:0-15
安全漏洞:
Itlb多重命中:不受影响
L1tf漏洞:不受影响
Mds漏洞:不受影响
Meltdown漏洞:不受影响
Mmio陈旧数据:不受影响
Retbleed漏洞:不受影响
Spec store bypass漏洞:通过prctl禁用了推测存储旁路
Spectre v1漏洞:通过用户空间拷贝/swapgs屏障和__user指针的清理来缓解
Spectre v2漏洞:通过Retpolines、IBPB条件、IBRS_FW、STIBP始终开启、RSB填充、PBRSB-eIBRS不受影响
Srbds漏洞:不受影响
Tsx async abort漏洞:不受影响

Disk:三星

Disk model: HFM512GD3JX013N                         
Disk model: SSD 970 EVO 500G

Mem: 美光科技 DDR4 8GB x 2

Set: 无
定位器: DIMM 0
插槽位置: P0 通道 A
类型: DDR4
类型详情: 同步非缓冲 (未注册)
速度: 3200 MT/s
制造商: Micron Technology
序列号: 00000000
资产标签: 未指定
零件编号: 4ATF1G64HZ-3G2E1
等级: 1
配置的内存速度: 3200 MT/s
最低电压: 1.2 V
最高电压: 1.2 V
配置的电压: 1.2 V
内存技术: DRAM
内存操作模式能力: 揮發性存储器
固件版本: 未知
模块制造商ID: 插槽 1,十六进制 0x2C
模块产品ID: 未知
内存子系统控制器制造商ID: 未知
内存子系统控制器产品ID: 未知
非易失性大小: 无
易失性大小: 8 GB

GPU: NVIDIA GeForce RTX 3050 Ti Mobile & Advanced Micro Devices, Inc.

*-独立显卡
描述: 3D 控制器
产品: GA107M [GeForce RTX 3050 Ti Mobile]
制造商: NVIDIA Corporation
物理标识: 0
总线信息: pci@0000:01:00.0
逻辑名称: /dev/fb0
版本: a1
宽度: 64 位
频率: 33MHz
功能: 电源管理、MSI、PCI Express、总线主控、ROM、帧缓冲
配置信息: 深度=32 驱动程序=nvidia 延迟=0 分辨率=2560x1600 可视颜色=truecolor 水平分辨率=2560 垂直分辨率=1600
资源: iomemory:fe0-fdf iomemory:ff0-fef IRQ:91 内存:fb000000-fbffffff 内存:fe00000000-feffffffff 内存:ff00000000-ff01ffffff I/O端口:e000(大小=128) 内存:fc000000-fc07ffff
*-CPU核显
描述: VGA 兼容控制器
产品: Cezanne
制造商: Advanced Micro Devices, Inc. [AMD/ATI]
物理标识: 0
总线信息: pci@0000:04:00.0
逻辑名称: /dev/fb0
版本: c4
宽度: 64 位
频率: 33MHz
功能: 电源管理、PCI Express、MSI-X、VGA 控制器、总线主控、帧缓冲
配置信息: 深度=32 驱动程序=amdgpu 延迟=0 分辨率=3840,2160
资源: iomemory:ff0-fef IRQ:50 内存:ff10000000-ff1fffffff 内存:ff20000000-ff201fffff I/O端口:d000(大小=256) 内存:fc500000-fc57ffff

台式装机注意事项

CPU选择

AMD R7 5800x3d

接口:AMD AM4|不支持核显|105W

京东 2099

主板选择

(ASUS)TUF GAMING B550M-PLUS WIFI II 重炮手

CPU接口 AMD AM4|DDR4 3800,4000 x4|wifi6 最大网络速度2500M|SATA x4|M.2(NVMe)x2|支持PCIE4.0 & 1个PCI Express x1 & 2个 PCI Express x16|电源接口24+8|版型M-ATX 24.4cm x 24.4cm

京东 829

显卡选择

微星(MSI)魔龙Z GeForce RTX 3060 GAMING Z TRIO 12G 超频版 

显存容量:12GB |电源接口8pin x 2 |三风扇| 尺寸 长324mm;宽140mm;高57mm|HDMI,DP|建议电源 550W以上|Cuda 3584 1777MHz

京东 2299

七彩虹(Colorful) iGame GeForce RTX 3060 Advanced OC 12G L 1867MHz GDDR6

显存容量:12GB |电源接口8pin x 2 |三风扇| 尺寸 315.5 131 52 |HDMI,DP|建议电源 550W以上|Cuda 3584 1777MHz

京东 2399

微星(MSI)魔龙 GeForce RTX 4060 Ti GAMING X TRIO 8G 

显存GB| Cuda 4352 2670MHz|电源8pin x 1

三风扇,尺寸338 141 52|双风扇,尺寸247 130 42

京东 3598 3298

内存选择

美商海盗船(USCORSAIR)32GB(16G×2)套装 DDR4 3600 台式机内存条

京东 539

硬盘选择

三星(SAMSUNG)1TB SSD固态硬盘 M.2接口(NVMe协议PCIe 4.0 x4) 980 PRO (MZ-V8P1T0BW)

京东 549

散热器

水冷

利民(Thermalright)Frozen Magic 360冰封幻境一体式水冷散热器C12风扇多平台ARGB冷头 支持LGA1700|散热器尺寸397x120x27 |电源接口4pin|散热器高度52mm

京东 469

电源

硬件配置:首先要考虑你计划使用的硬件配置,包括主板、处理器、显卡、内存、存储设备等。不同的硬件配置对电源功率的需求有所不同。查阅各硬件组件的功耗规格,以了解它们的功率需求。主板(MB)功率+CPU功率+GPU功率+内存(Mem)功率+硬盘(Disk)功率+散热器功率

余量:为了确保电源的稳定性和可靠性,建议选择功率略高于实际需求的电源。保持一定的功率余量可以应对未来可能的升级或添加其他设备的情况。

80 PLUS认证:考虑选择具有80 PLUS认证的电源。80 PLUS认证是一项标准,用于衡量电源的能效水平。认证级别包括80 PLUS、80 PLUS Bronze、80 PLUS Silver、80 PLUS Gold、80 PLUS Platinum和80 PLUS Titanium,其中Titanium级别是效率最高的

品牌和质量:选择知名品牌的电源,这样更有保障质量和可靠性

先马(SAMA)ONCALL 750W 台式电脑主机箱电源 全模组/80PLUS金牌/台系电容/宽幅/节能温控/额定功率750W

支持3060 4060ti|长140mm;宽150mm;高86mm

京东 599

先马(SAMA)白金1200W 台式电脑机箱电源 80PLUS白金认证/全电压/固态电容/12cm风扇/全模组线材/额定1200W

支持4090,RX 6950 XT,更高功率显卡|长187.8mm;宽145.7mm;高86mm

京东 1099

机箱

主板型号要和机箱匹配,ATX,MATX, ITX三种,机箱尺寸

CPU散热器风扇高度

是否支持水冷位,128/240/280/360,水冷风扇厚度限制(冷排体积),水冷头高度(冷头体积)

电源体积限制,有电源仓的机箱,要注意,一般选择标准ATX电源 140 ,150,86

显卡体积限制,一般限制长度

硬盘位数量

理想价位300~700

品牌 乔思伯, 先马

主板+CPU 3000, 先开2000左右,内存+固态 1000左右 电源+机箱 1500左右 ,散热器500左右

线程基础知识

基本概念

线程(thread)是系统调度分配的最小单位。与进程相比,线程没有独立的地址空间,多个线程共享一段地址空间,因此线程消耗更少的内存资源,线程间通信也更为方便,有时线程也被称为轻量级的进程(Light Weight Process,LWP

进程作为系统调度分配单位时存在的弊端

进程是资源拥有者,使用独立的地址空间,当系统中切换资源时,内存中进程的数据段、代码段、以及堆栈都要被切换(进程上下文切换),这种情况下无论是时间消耗和空间消耗都相当大。操作系统允许多进程并行执行,进程较为庞大,多进程占用的空间(内存)相当客观,满足大负载需要更大的内存。为了解决以上问题,诞生线程,更小的调度单位。

线程的机制

linux系统中线程借助进程机制实现,线程与进程联系密切,进程可以蜕变为线程。当在一个进程中创建一个线程时,原有的进程就会变成线程,两个线程更有一段地址空间;线程又被称为轻量级进程,线程 TCB(Thread Control Block,线程控制块)与进程 PCB相同,因此也可以 TCB视为PCB;对内核而言,线程和进程没有区别,CPU会为每个线程与进程分配时间片,并通过PCB来调度不同的线程和进程。

linux系统中的线程分为三种:

内核线程

内核线程是内核的分支,每个内核线程可处理一项特定操作。

用户线程(协程)

用户线程完全是建立在用户空间的线程,用户线程的是完全建立在用户空间的线程,用户线程的创建,调度,销毁 操作都在用户空间未完成,是一种低消耗的,高效率的线程。

轻量级线程(LWP

一种用户线程,同时也是内核线程的高级抽象,每一个轻量级线程都需要一个内核线程的支持,轻量级线程和内核线程及CPU之间的关系如图

相关参考

https://wiki.swoole.com/#/coroutine

setInterval轮询问题记录

一个electron项目,在使用setInterval轮询时,出现了网络崩溃的系统错误。 在setInterval中执行console.log显示setInterval还会执行,但是axios不会重新发起ajax请求。其中getControlStatus轮询后端接口获取数据

renderer.js:1 Uncaught (in promise) SystemError [ERR_SYSTEM_ERROR]: A system error occurred: undefined returned undefined (undefined)
    at Object.networkInterfaces (os.js:203)
    at t.default (renderer.js:12)
    at a.<anonymous> (renderer.js:26)
    at r (renderer.js:26)
    at Generator._invoke (renderer.js:26)
    at Generator.forEach.e.<computed> [as next] (renderer.js:26)
    at i (renderer.js:1)
    at renderer.js:1
    at new Promise (<anonymous>)
    at new t (renderer.js:12)
addCodeToName @ internal/errors.js:306
SystemError @ internal/errors.js:165
NodeError @ internal/errors.js:250
checkError @ os.js:64
hidden @ internal/errors.js:294
networkInterfaces @ os.js:203
t.default @ renderer.js:12
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26
setInterval (async)
resetControlStatusRequest @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
handleControlOrder @ renderer.js:26
(anonymous) @ renderer.js:26
r @ renderer.js:26
(anonymous) @ renderer.js:26
forEach.e.<computed> @ renderer.js:26
i @ renderer.js:1
(anonymous) @ renderer.js:1
Promise.then (async)
i @ renderer.js:1
(anonymous) @ renderer.js:1
t @ renderer.js:12
(anonymous) @ renderer.js:1
getControlStatus @ renderer.js:26
(anonymous) @ renderer.js:26

setInterval存在的问题

对自己调用的代码是否报错会无视掉。即自己调用的代码即使错误,也会继续执行下去,这就是导致上述问题获取接口失效原因。

setInterval无视网络延迟
我们在向服务器轮询数据的时候,如果发生网络卡顿的情况,客户端收到请求响应的时间大于interval循环的时间。而setInterval会无视任何情况下继续定时执行,这就会导致了用户的客户端里充斥着客户端的请求

参考文章

项目经历之——轮询后端接口(setInterval、websocket)

MDN文档:确保执行时间短于定时器时间间隔

Javascript 开发生态 常用笔记

Nodejs相关

版本管理开发环境nvm

进程管理工具 PM2

依赖包管理工具 pnpm npm yarn

pnpm(Performant npm) 更高效的包管理工具,使用硬链接和符号链接来减少磁盘空间的占用。磁盘空间利用率更高,安装速度更快。能够共享 node_modules 中的依赖,不同项目之间的依赖不会重复安装兼容 npm 的 package.json 文件

yarn facebook出品的包管理工具 并行化下载,速度更快 更好的锁定文件(yarn.lock),解决依赖版本一致性问题 更友好的命令行输出和更好的依赖树结构 支持离线安装

VSCODE工具

vetur

官方文档

项目配置文件jsconfig.json,使用vuecli创建项目时自动生成

格式

eslint

GUI相关

前端好用的轮子汇总

electronjs

Web音视频开发

Web音视频入门系列——音视频基础知识

Web 视频播放的那些事儿

音视频播放过程中的问题解决(播放质量优化)

Media container formats

HDR和SDR的区别

关于H.264的码率,720P、1080P输出比特率设置

mp4视频转换格式,使用H.264编码,比特率512-1024可以比较好的在大小和画面质量上取得平衡。其他编码或使用自动比特率,将导致mp4视频在页面中只有声音,没有画面。

文件的扩展名

MIME类型

容器格式

编码方式

视频基础概念

分辨率

1280×720 (720p) 1920×1080 (1080p) 2560×1440(2k) 3840×2160 (4k)

帧率

25fps,30fps,60fps

比特率(码率)

比特率是单位时间播放连续的媒体如压缩后的音频或视频的比特数量。

在这个意义上讲,它相当于术语数字带宽消耗量,或吞吐量。比特率规定使用“比特每秒”(bit/s或bps)为单位,经常和国际单位制词头关联在一起,如“千”(kbit/s或kbps),“兆”(百万)(Mbit/s或Mbps),“吉”(Gbit/s或Gbps)和“太”(Tbit/s或Tbps)
虽然经常作为“速度”的参考,比特率并不测量“‘距离’/时间”,而是被传输或者被处理的“‘二进制码数量’/时间”,所以应该把它和传播速度区分开来,传播速度依赖于传输的介质并且有通常的物理意义

视频格式&编码格式

MP4、AVI、WebM、MOV、WMV、RMVB、FLV

AVCH.264,H.265 VP8,VP9

音频基础概念

采样率

比特率(码率)

音频编码&&音频格式

MP3 AAC WAV FLAC

PHP安装PECL扩展

查看模块是否安装

phpinfo(); 页面调用函数
php -m 查看已安装模块
php –ini 查看php.ini的位置
php –ri gd 查看模块信息

GD

查看是否支持webp

php --ri gd | grep WebP

Imagick

举例,查看imagick是否安装webp支持

 php --ri imagick | grep WEBP

安装imagick支持webp php处理

模块安装

php安装 pear 文档

wget http://pear.php.net/go-pear.phar
#指定php目录安装pear
sudo /usr/local/php/bin/php go-pear.phar

安装之后可以使用pear 和pecl命令安装扩展

方式一 使用pear相关命令

PEAR命令 安装扩展文档

pear install extension_name
pear upgrade extension_name
pear install --onlyreqdeps html_page2

参数
-onlyreqdeps (install required dependencies (依赖) only) 安装需要依赖
–alldeps (install all dependencies (依赖) ) 安装全部依赖

方式二

pecl命令文档

方式三

phpize源码编译安装 (共享/动态 扩展) 以redis为例

上https://pecl.php.net/下载好扩展的源码包 redis-6.2.7.tar.gz

tar -zxvf redis-6.2.7.tar.gz
cd redis-6.2.7
/usr/local/php/bin/phpize 
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install 
#写入配置
 echo 'extension=redis.so' > /usr/local/php/etc/php.d/redis.ini

扩展静态编译到php中

参考文章

PHP PECL 使用

计算机图像处理知识体系

图像文件类型与格式指南


类型 优点 缺点 相同图片大小比较 背景能否透明
BMP 无损压缩,图质最好 文件太大,不利于网络传输 152K 不可以
GIF 动画存储格式 最多256色,画质差 53K 可以
PNG 可保存透明背景的图片 画质中等 202K 可以
JPG 文件小,利于网络传输 画质损失 84K 不可以

浅谈数字图像处理之图像在计算机中的表现形式

图像如何存储在计算机中?

计算机只认识0和1但是怎么表示图像和影视等等众多应用的?

【计算机视觉处理二】图像的基础知识

图像处理基础知识——图片存储形式、色域、图片文件格式

WebP 相对于 PNG、JPG 有什么优势?

如何生成webp动图

几种 WebP 动态图制作方法

动态 WebP 图片 Chrome 版本32+ 才支持.