WorkNormalRecord
虚心听取建议和意见,多学习,多看看有效的代码以及学习编程和业务理解思想。
命令记录
1 |
|
Curl各个阶段时间
1 |
|
Timing web requests with cURL and Chrome (cloudflare.com)
K8s 安装网络工具
1 |
|
1 |
|
知识点记录
线上环境和测试环境访问通过Switchhost切换再访问。
开发新功能一定要兼容之前的版本,注意字段变更和逻辑判断问题。
写代码之前先规划一下大体结构,注意代码的优化,注意细节问题的把握。
注意日志的合理打印,不要都等有问题之后再加日志,注意日志的格式和级别。
对于代码的安全问题要严格进行效验,前后端都需要,不能嫌麻烦就不处理。
redis设置key时要添加统一前缀,比如UserID_1001:对象内容
代码中多处出现的相同的代码提取成方法来进行简化,数字进行常量提取优化
做原来的东西的修改操作时一定要仔细考虑到影响范围,要考虑到是否会影响其他东西
go strcut可以通过 Name int
json:"name,string"
来指定该字段使用string类型接收来转换。1
2
3
4
5type User struct {
Name int `json:"name,string"`
Age bool `json:"age,string"`
}
可以将string类型的json转换为对应的类型go - redis的setnx和hsetnx是同步的,并且同类型键值存在不会报错,虽然是string和hash两种,但是也不能出现key相同。
先set a 然后再hset/hsetnx a,会报错,先Hset a 然后再set a,会把之前的hash覆盖,如果是setnx则不会报错,也不会修改原hash,不会覆盖。
time.Duration(0) redis过期时间设置0 为永久
Redis 删除不存在的key不会报错,del srem都一样
状态码5XX表示服务端错误。
状态码 | 含义 |
---|---|
500 Internal Server Error | 服务器内部错误,服务器处理请求的过程中出现一个错误(内存地址越界、空指针等),导致服务器无法继续处理请求。 |
502 Bad Gateway | 网关错误,网关请求服务器,在网关设置的超时时间之内服务器中断请求,即没有正常返回数据。 1. 服务不可用,网关找不到对应的upstream。 2. 服务进程被杀掉,php服务设置超时时间主动杀掉进程。 3. 服务进程为长连接,断开过程中被复用。 |
504 Gateway Timeout | 网关超时,网关请求服务器,到了网关设置的超时时间之后服务器仍然没有返回数据。 |
- find . -name “*.go” | xargs cat | wc -l 查询项目代码行数.
- ctx.shouldBind既可以接收Get参数也可以接收Post参数,更加灵活.
- 新服务部署完后需要配置deployment的yaml配置文件
配置后才能正常的访问内网环境域名的接口
1 |
|
- MySQL select…… For update 对于查询的数据加锁,避免其他的事务操作修改数据
https://www.cnblogs.com/moyui/articles/12051588.html
- 查看文件大小命令
1 |
|
- gorm的In查询的注意点
1 |
|
- gorm数据库查询排序,优先根据a字段降序,再根据b字段降序
1 |
|
- 系统设计原则
系统设计开发过程中遵循的基本原则,包括架构设计、功能实现、代码编写。
简单适用原则
简单,要求设计简单、理解简单、维护简单,意味着容易学习上手、开发维护成本小、不容易出问题;适用,要求系统应能够通过合适的方式满足业务需求,意味着系统应当面向我们的业务特性量身定制。
简单适用原则,要求设计应当以最简单优雅的方式,满足业务需求。能够用简单的方式解决的问题,就不要用更复杂的方式,不炫技;一些目前预见没有必要的功能,不需要实现,但在设计时应当为后续的实现预留条件,并避免过度设计。
最大共性原则
最大共性原则,要求在设计过程中,跳出具体的业务功能需求,从更高的视角寻找业务的共性,抽象出业务模型,针对业务模型进行开发, 进而通过业务模型实现功能需求。
优秀的业务模型,能够在后续的持续开发迭代中保证系统的逻辑一致性和可扩展性,降低开发成本并延长系统的使用周期, 避免通过不断拷贝代码、增加逻辑分支而陷入开发的绝望循环。
项目代码开发规范
【强制】时间相关字段无特别说明MySQL中类型使用 int(11) 无符号 (支持 0-4294967295), golang中类型使用int64;
【强制】学生ID字段统一用stuId,数据库字段类型 bigint(20)无符号,golang中类型使用int64;
【强制】和环境(测试、灰度、生产环境)相关配置统一到app的configs中,禁止在代码中硬编码;
【推荐】数据逻辑处理,特别是涉及到多表的逻辑,尽量在biz层处理, 开启事务除外;
【强制】api的Response输出字段统一使用驼峰命名;
【强制】数据库表名、字段全部使用小写,单词间下划线分割;
【强烈推荐】Redis key 统一使用小写,统一增加前缀growth,功能或库表分割使用英文冒号(:),其他分隔符使用下划线(_), 复杂类型的field命名使用驼峰;
【强烈推荐】日志打印原则:谁报错谁打日志的原则,即:data内报错, 由data打印错误日志,biz层直接调用data产生的错误可不打印日志; 但biz内调用data后数据处理发生的错误应该有biz层自行打印错误日志;
【强烈推荐】打印错误日志时,要把关键参数或数据放到日志中, 不要仅打印error信息;
【强烈推荐】方法或函数要加注释,特殊逻辑要加详细注释甚至文档链接加以说明;
【强烈推荐】data层入参是结构体时,要对必需属性做校验,防止外层调用漏传,进而写脏数据;
【强烈推荐】数据库新增操作:使用结构体进行创建的时候,对于有值的字段采用select区分出来,避免数据库默认值设置错误问题。比如is_deleted默认值为-1,不是字段零值;
【强烈推荐】数据库修改操作:尽量使用map结构映射字段进行更新,使用结构体更新会存在零值更新失败的问题;
【强烈推荐】数据库查询操作:尽量使用Take、Last、First进行查询,使用Find进行查询的时候查询不到不会报错,前面三个会报错record not found;
【强烈推荐】MySQL字段都设置为NOT NULL,并设置默认值;
【强制】ToC接口统一使用POST,不再区分GET和POST,和客户端使用保持统一;
Dockerfile模板
1 |
|
- 忽略已经加入版本管理的文件
如果某些文件已经被纳入了版本管理中,直接修改.gitignore是无效的。需要先把文件从版本管理的索引中删除,然后修改.gitignore文件,然后提交即可。
1 |
|
- go替换依赖资源包为本地文件
1 |
|
- Gin框架的shouldBind方法针对json格式的参数一次请求只能使用一次,不能多次使用,绑定参数的时候有多次绑定的情况需要额外注意前端传参的格式已经接口的协议是GET还是POST。
https://www.cnblogs.com/davis12/p/16355634.html
1 |
|
- tree 文件目录 ,这个命令可以获取文件结构
1 |
|
- 设置header头的时候不论大小写,在真正进行http/https请求的时候,不同的web框架会将header头转换为不同的格式。php fend框架会转换为HTTP_原key全大写,go gin框架会转化为全驼峰。
- redis缓存多处同时插入缓存值时候容易造成并发问题记录。
以下以redis的List类型举例:
- 不加锁
- 接口A—>查询key是否存在—>不存在插入缓存(叠加的方式)
- 接口B—>查询key是否存在—>不存在插入缓存(叠加的方式)
这种情况下,当接口AB同时请求的时候,会造成A,B都查询到key不存在的情况,然后就会进行写入,造成数据叠加出错。
- 加锁 redis setnx 分布式锁,defer del key expire 3s
- 接口A—>查询key是否存在—>不存在—>逻辑操作—>获取锁—>获取成功—>插入缓存(叠加的方式)—>释放锁
- 接口B—>查询key是否存在—>不存在—>逻辑操作—>获取锁—>获取成功—>插入缓存(叠加的方式)—>释放锁
这种情况下,假如接口同时请求都查询到了key不存在进行获取锁的操作,如果接口A获取成功,但是获取成功后进行后续的逻辑操作速度很快,处理完成后就释放锁,这个时候在极端情况下接口B也会出现获取到锁的情况,同样也会出现数据叠加插入的情况。【特别是在判断key是否存在和获取锁之间有其他的逻辑操作的情况下,更容易出现此类问题】
- 加锁 redis setnx 分布式锁,defer del key expire 3s,获取锁成功后再判断key是否存在,类似于双重检测锁
- 接口A—>查询key是否存在—>不存在—>逻辑操作—>获取锁—>获取成功—>查询key是否存在—>不存在—>插入缓存(叠加的方式)—>释放锁
- 接口B—>查询key是否存在—>不存在—>逻辑操作—>获取锁—>获取成功—>查询key是否存在—>不存在—>插入缓存(叠加的方式)—>释放锁
这种情况下,即时A获取锁之后很快处理完就释放了锁,就算极端情况下接口B也获取成功了锁,但是这个时候再去查询key是否存在就必定存在了(即时A接口缓存写入失败,也不会出问题),就不会进行后续的插入缓存操作了。
如果是string类型,可以使用setnx这些的命令来进行处理,但是List类型没有类似的命令就需要自己加锁来避免并发问题,为了避免缓存多次写入造成数据重复,也可以使用set来处理,对于排序有要求的可以使用zset,总之,办法很多,选择适合当前的项目开发即可。
- 阿里云日志库查询日志特殊语句记录,当我们需要匹配output输出字段里面的部分字符串的时候,可以使用如下语句进行查询,#代表后续不进行分词。
1 |
|
- 项目代码中要尽量避免出现如下代码的情况,当数据量比较大的时候,接口的耗时就会成倍增加。
1 |
|
- 在项目代码的数据库设计中,如果某个字段会比较长,比如订单记录或者其他记录的唯一标识的字段[76074586-2001200-221507607-2097321-22205789_23402135_1_744605_0],这种情况下需要特别注意数据库中对应字段设置的长度是否满足。因为某些情况下执行insert操作,超过数据库指定的字段长度也不会报错,会自动截断,这取决于数据库是否设置开启了严格检测模式。
https://blog.csdn.net/u010738038/article/details/137768633
1 |
|
- 启动脚本文件执行命令
1 |
|
Ping和Telnet是两种不同的网络工具,它们用于不同的目的。以下是它们的主要区别:
- Ping:主要用于检测网络连通性和诊断网络问题。
- Telnet:主要用于远程登录和管理系统,以及测试特定端口的连通性。
Ping
功能:
- 用于测试主机之间的连通性。
- 通过发送ICMP(Internet Control Message Protocol)回显请求包并等待回显应答来确定目标主机是否可达。
使用场景:
- 检查网络连接状况。
- 测试网络延迟和数据包丢失率。
协议:
- 使用ICMP协议。
命令示例:
bash复制
ping example.com
输出信息:
- 显示往返时间、TTL值以及成功与失败的数据包统计信息。
Telnet
功能:
- 用于远程登录到另一台计算机,通常用于管理设备或服务器。
- 提供一个命令行接口,可以执行各种操作。
使用场景:
- 远程访问和管理服务器。
- 测试特定端口是否开放。
协议:
- 使用TCP协议,默认端口为23。
命令示例:
bash复制
telnet example.com 80
输出信息:
- 建立连接后会显示远程系统的提示符,允许用户输入命令进行交互。
Gorm框架Upsert使用,创建或者更新,如果存在记录则进行更新,如下两种方式
1. 通过ON DUPLICATE KEY来实现创建或更新 需要有唯一主键或者唯一索引才能支持,一条sql, 会导致主键不连续,每次执行的时候主键都会递增,不管本次操作是插入还是更新。
1 |
|
2.通过FirstOrCreate 来实现创建或更新 先查询 然后再根据情况创建或更新,两条sql。这个方法实现的upsert不会导致主键不连续,也不依赖唯一索引,更加灵活。
1 |
|
- Go “github.com/spf13/cast” 包转换字符串为int的时候有坑,cast.ToInt()。
1 |
|
从数据量比较大的MySQL表里面随机取10条数据,怎么实现比较好?
使用MySQL自带的函数Rand()
1 |
|
ORDER BY RAND()
的实现原理相对简单,但在大数据集上可能会影响性能。以下是这个过程的基本步骤:
生成随机数:对于每一行,MySQL 会使用
RAND()
函数生成一个介于0和1之间的随机数。排序 :然后 MySQL 对这些随机数进行排序。这意味着每一行都会被赋予一个随机值,并且整个表的数据将根据这些随机值重新排列。
限制结果:最后,使用
LIMIT 10
来返回前10条记录。
另一种方法是创建一个包含所有主键的临时表或缓存,然后从中随机选择:
创建一个包含所有主键的临时表:
CREATE TEMPORARY TABLE temp_keys AS (SELECT id FROM your_table_name);
从临时表中随机选择10个主键:
SELECT * FROM your_table_name WHERE id IN ( SELECT id FROM temp_keys ORDER BY RAND() LIMIT 10 );
这减少了排序操作的范围,从而提高了效率。
查询数据库的最大主键id,然后通过工具函数生成0-最大主键值之间的10个随机数,然后根据随机数查询对应的记录。
此方法查询通过主键id查询效率高,把随机数生成放在代码逻辑里面,适用于递增主键。
查询日志中某个记录出现相同的次数
1
2
3语句格式:查询语句 | 分析语句
实例:
init roundNo1 success and InitNovActRoundTaskFinishCache | SELECT msg, COUNT(*) as DuplicateCount GROUP BY msg HAVING DuplicateCount > 1