Golang 1.22.2
在项目中对应数据库的唯一id,我们通常会选择使用数据库自增id,uuid,雪花算法等,每种模式的id都有各自的优缺点,这里将通过Redis来实现一种自定义分布式的id生成模式。
当然这种实现方式也有一定的缺点,那就是过于依赖redis,一旦出现redis不可用,会导致id生成失败,从而影响整个业务的不可用,所以在设计的时候需要考虑,如果redis不可用如何自动启用其他唯一id生成模式。
Golang 1.22.2
在项目涉及到了一个功能点,就是文件的移动,最开始是在windows下使用,然后发布到linux,业务第一阶段文件是一个分区下,代码还能正常运行,后期文件太多,一个分区装不下了,这时扩容了一个新的分区,然后就出现了*LinkError.
错误,看到源码才知道,在非Unix
系统下即使在同一个目录,Rename 不是原子操作。
,源代码说明如下:
Golang 版本:1.22.2
为了更好的处理 Golang Cmd 的日志输出,我们可以先查看exce.Cmd 结构体的定义。在代码中可以 Stdout io.Writer
和 Stderr io.Writer
两个字段,一个进程的标准输出和标准错误输出可以通过这两个字段来指定。
简而言之我们只需要实现一个 io.Writer 接口的结构体,然后将这个结构体赋值给 Cmd 结构体的 Stdout
和 Stderr
字段即可。
Golang本版:1.22.2
出现的场景,在golang项目中需要管理shell脚本的执行,主要实现关闭进程的代码如下:
gofunc (s *Streamer) Kill() error {
s.mu.Lock()
defer s.mu.Unlock()
// 首先关闭输出流
if closer, ok := s.Cmd.Stdout.(io.Closer); ok {
if err := closer.Close(); err != nil {
log.Printf("Failed to close stdout: %v", err)
}
}
if closer, ok := s.Cmd.Stderr.(io.Closer); ok {
if err := closer.Close(); err != nil {
log.Printf("Failed to close stderr: %v", err)
}
}
if s.Cmd.Process != nil {
// Kill the process
if err := s.Cmd.Process.Kill(); err != nil {
return err
}
}
// 等待进程关闭
return s.Cmd.Wait()
}
在前端调用接口触发方法Kill时发现时不时出现接口请求超时,一开始以为是网络的问题,后面经过过排查,发现Cmd.Wait()
一直没有结束,导致接口请求超时。在查找资料的过程中发现,Cmd.Wait()
会一直等待进程结束,如果进程一直没有结束,那么Cmd.Wait()
也会一直等待,然而实际情况是shell已经执行完毕,经过排查是产生了僵尸子进程。