自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

liyunlonghere

你必须非常努力,才能看起来毫不费力。

  • 博客(197)
  • 收藏
  • 关注

原创 pg表字段自动生成go结构体(配合goland)

pg表字段自动生成go结构体

2022-06-12 23:05:28 518 1

原创 退避延迟重试队列

延时队列

2022-02-25 18:12:52 324

原创 golang no cancelable context

在开发过程中,我们可能经常遇到需要异步处理的任务,主协程可能不会等待异步任务的完成就结束,传递给异步任务的是主协程的context,主协程退出导致context被cancel, 影响异步任务。如果简单的给异步任务传递context.Background,可能导致一些value缺失,如trace信息。因此,需要一种no cancelable的context,能继承主协程中context的所有value,同时不继承其cancel机制,我们可以通过以下方法来实现。// PropagateContext

2022-02-25 15:19:13 609 1

原创 golang动态限制并发数量

golang动态控制并发数量

2022-02-17 15:48:54 2320

原创 消息系统设计

消息系统设计存储消息发件箱收件箱消息结构消息类型拓展校验内容拉取消息PS:最近在做一些消息相关的内容,对消息做了一下总结,包括发送、接收、存储等,记录一下,欢迎大家交流拓展。存储消息redis临时存储,数据结构zsetkafka异步持久化到db,由于消息表数据量比较大,msg表按照createdTime分区。发件箱sendBox redis zset实现。zadd nx,key:固定前缀+senderId,score:msgId,member.

2021-11-24 18:44:47 1224

原创 SQL优化

最近在做一些SQL优化的事情,在这里记录一些SQL优化的过程与想法,希望可以给其他遇到同样问题的人一些思路与灵感。单纯加索引解决 关系表,有查询关系的SQL:select * from relationships where user_id = ? and relation_type = ? and updated_time < ? order by updated_time desc limit ? 未加索引,加索引解决。(user_id+relation_type+updated_t

2021-10-09 18:40:32 237

原创 爬虫服务(chromedp)僵尸进程排查记录

目录发现现象如何解决?临时解决根本上解决修复过程发现现象爬虫服务会使用chromedp库(https://github.com/chromedp/chromedp)模拟浏览器登录,抓取网页数据,某天在pod内查看服务运行状态时,发现有大量的zombie进程,看了下是Chrome进程。爬虫服务使用Chrome,应该是以创建子进程的方式来启动Chrome,如果在子进程销毁时没有wait或者waitpid来处理,那么子进程会成为zombie进程。每个zo..

2021-08-04 17:52:25 2242

原创 golang手动实现error group

手动实现了下go error group,并发请求、请求数量限制、出错时cancel掉所有task,以下为示例,要求task是可cancel的!package mainimport ( "context" "errors" "fmt" "sync" "sync/atomic" "time")const ( M = 2 N = 8)func main() { ctx, cancel := context.WithTimeout(context.Background.

2021-02-26 16:13:12 701

原创 go实现N个goroutine交替打印数字

go中CSP模型提倡“不要以共享内存的方式来通信,相反,要以通信来共享内存”,go的CSP模型,就是通过goroutine和channel结合的形式来实现的。这里通过goroutine和channel实现了一个简单的并发控制,即通过channel在不同的goroutine之间传递信息,而不是通过锁的形式,或者是共享变量的形式来实现。例如要实现3个goroutine交替输出1-30的数字,可以参考下面的实现方法:下方会有解释func getWorker(waitCh chan int, s

2020-10-10 16:59:18 2265 1

原创 golang常驻后台类worker模板

golang中经常会用到常驻后台类的worker,实现例如消费队列、定期执行任务、定期统计数据等功能。这里自己实现了通用的worker模板,主要有以下功能:panic自动重启,最大重启次数可自定义。 optional参数,有默认参数和支持自定义参数。 busy模式和idle模式,执行完任务后睡眠不同的时间。 支持以一定的频率执行,例如每5分钟执行一次任务。 可动态的通过channel控制任务的启动和暂停。ps:此处可结合etcd实现分布式选主机制。 支持用context优雅的停止,work

2020-08-28 13:54:45 1003

原创 使用etcd实现动态分布式选主

日常开发中经常会有后台运行的worker类任务,由于服务是分布式的,我们可能会有多个分布式的worker同时在运行,有时候我们需要分布式下只有一个worker在运行,这时候就可以用到etcd的分布式选主。etcd中concurrency包下已经帮我们实现好了选主,我们只需要调用其api实现就可以了,下面我们分析下etcd是如何实现选主机制的。直接进行源码分析:// Campaign puts a value as eligible for the election on the prefix

2020-07-27 20:07:15 5253

原创 istio内置资源和sidecar注入初探

Gateway(gw) VirtualService(vs) DestinationRule(dr) ServiceEntry(se) sidecar注入以及流量劫持 sidecar注入过程 sidecar注入原理 sidecar注入结果 Gateway(gw)istio中gateway资源可以将网格内部的服务暴露给网格外部的服务,供网格外部的服务调用,该资源描述了需要公开的端口、端口的协议类型、以及域名等。下面是服务的gw资源配置文件示例。 1 2...

2020-05-13 14:45:07 1409

原创 Kubernetes Controller Manager原理浅析

controller manager是什么?Controller Manager 是集群内部的管理控制中心,负责统一管理与运行不同的 Controller ,实现对集群内的 Node、Pod 等所有资源的管理。比如当通过 Deployment 创建的某个 Pod 发生异常退出时,RS Controller 便会接受并处理该退出事件,并创建新的 Pod 来维持预期副本数。contro...

2020-05-08 14:39:42 2188

原创 线上golang grpc服务资源泄露问题排查

前几天告警群里报出一个go服务grpc接口出现很多超时现象,排查发现是服务有内存泄露与cpu占用高的问题,在这里将排查的过程记录一下,给大家提供排查问题的方向与思路,同时借鉴教训,优化自己服务代码。发现超时现象后,登录机器看了下top,该服务总共有两台机器,发现02机器的cpu与内存占用很高(如下图第一个进程),而01机器都很低。正常情况下不会有这么高的资源占用,可能是服务有资源泄露的问题,资...

2020-04-02 18:37:13 4557 1

原创 golang sync.Mutex锁如何实现goroutine的阻塞与唤醒初探

var mu = new(sync.Mutex)func test() { mu.Lock() defer mu.Unlock() ...}这是一段mutex的加锁解锁代码,当多线程同时执行这段代码时,能保证我们临界区的代码是顺序执行的。新来的goroutine可能直接获取到锁,也可能被阻塞,这里探究一下goroutine是如何被阻塞和唤醒的。由于mutex实现复杂,牵扯知识很多,我...

2020-03-19 17:20:54 2698 1

原创 golang echo web框架中间件的实现

使用echo框架可以方便的定义自己的中间件,这里研究下echo中间件的实现以及是如何实现链式调用的。比如我们有下面的中间件:func CalHandleTime(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) (err error) { start := time.Now() defer fu...

2020-01-19 18:09:05 2401 1

原创 grpc负载均衡RoundRobin源码解读

grpc client端创建连接时可以用WithBalancer来指定负载均衡组件,这里研究下grpc自带的RoundRobin(轮询调度)的实现。源码在google.golang.org/grpc/balancer.go中。roundRobin结构体定义如下:type roundRobin struct { r naming.Resolver w naming.Wat...

2019-12-26 23:36:54 2160

原创 grpc复用client连接

以前在调用grpc接口时,总要调用Dial函数来创建一个grpc的ClientConn,如果每次都要创建,那么开销代价是很大的。grpc的ClientConn对象可以帮我们实现自动重连的机制,并且是并发安全的,因此可以定义一个全局的ClientConn,然后用到的时候就用这个连接。下面是简易实现:package delayqueueimport ( "google.golang...

2019-09-17 15:18:30 9882 1

原创 golang实现简单的goroutine worker池

实现了简单的worker池,可以执行一些后台常驻类的任务,并且可以实现worker数量的实时控制。利用两个worker数组,alive和idle,分别保存活跃的worker和空闲的worker,并且空闲的worker可以从暂停状态快速转变为活跃状态。由于每次在增加worker数量的时候没有创建goroutine的情况,所以效率会稍微高一些。type taskFunc func() err...

2019-09-05 20:33:39 675

原创 golang利用redis实现简单延时队列

redis的zset是一种能自动排序的数据结构,我们可以用这个特性来实现简单的延时队列。利用zadd将数据添加到zset中,每个数据的score值设置为数据的延时时间+当前时间戳,后台goroutine不断zrange轮询zset,取出score值小于当前时间戳的数据,然后再对数据进一步处理,这样就实现了简单延时队列的功能。Zaddzadd支持批量添加的功能,有需要可以自己去探索下,这里...

2019-05-08 19:45:57 2628

原创 golang利用redis实现消息队列Push和Pop

可以利用redis的list结构来实现消息队列功能,使用lpush、rpush来实现入队,lpop、rpop来实现出队列。我们统一从左边push、从右边pop,即用lpush和rpop组合。当list中没有元素时,rpop会返回nil,这样我们需要不断用轮询队列,直到队列中有元素,然后pop出来。为了避免不断轮询带来的性能损耗,我们这里使用brpop命令,brpop使用了系统提供的阻塞...

2019-05-08 18:22:16 6906

原创 golang利用redis实现限速器

利用redis的String数据结构可以实现计数器的功能,利用incr或者incrby来实现计数器的增加或者减少。同时redis对可以对key实现过期功能,这样我们就可以利用计数器和过期功能来实现限速器。例如很多时候我们需要对单个用户进行限速,每分钟或每秒钟限制limit次,可以使用user_id作为key,访问次数作为value,到redis进行存储,当用户访问一次,我们就incr一下;...

2019-05-05 21:11:21 2397

原创 golang使用redis实现分布式锁

redis可以使用string数据结构来实现分布式锁。这里记录一些注意点:setnx:利用setnx的特性,当key不存在时,可以设置成功;当key存在时,setnx返回nil。 设置expire:为了防止客户端获取到锁后忘记解锁,这里设置了锁的过期时间。并且由redis来保证setnx和expire是原子操作,否则可能出现在setnx后可能未设置expire的情况。 超时问题:由于设置了...

2019-05-04 20:54:02 5825 2

原创 redis基础数据结构以及其应用

最近在看redis相关的书籍,这里将一些知识点做下总结,以免以后遗忘。主要包含redis基础数据结构、redis的一些策略以及redis的一些应用等内容。String实现redis的字符串是简单动态字符串,可以对其进行动态修改。策略空间预分配当对字符串进行append操作时,如果修改后的字符串长度len小于1MB,那么redis会分配跟len大小相等的fr...

2019-05-04 18:42:52 233

原创 golang functional options,优雅的初始化对象实例

当我们定义了一个对象时,一般会创建一个方法方便外部初始化一个实例。如下面的例子:type Client struct { timeout int64 dialFunc func() error healthCheck func() bool}func NewClient(timeout int64, dialFunc func() error, healthChec...

2019-04-05 22:55:36 3990

原创 redigo批量lpush/rpush、批量zrem

在使用redigo库时,想批量向redis list中批量push,发现像下面方式传入[]string是不行的,在这里记录一下。keys := []string{"nn", "mm"}_, err = con.Do("lpush", queueName, keys)直接传slice发现结果是整个slice被拼在一起放到一起了:后来google了下,发现需要将slice用三个点...

2019-03-24 19:19:57 4042 2

原创 漏桶算法

近期在研究Jaeger,Jaeger中有一种采集策略是速率限制类型,内部使用的是漏桶算法,在这里研究了下Jaeger漏桶算法的实现原理,自己仿照其实现了一个rateLimiter,并进行了相关测试,下面是主要实现。lck:lck是互斥锁,主要用来防止并发情况下产生错误。 rate:速率,即接口每秒限制多少个请求。在这里也就是水滴从漏桶中流出的速度,同时也是余量增加的速度。 balance:...

2019-03-12 21:06:36 1972

原创 opentracing: jaeger在grpc中的简单实现

参考项目:https://github.com/grpc-ecosystem/grpc-opentracing之前用函数调用实现了简单jaeger-demo(https://blog.csdn.net/liyunlong41/article/details/87932953),函数之间利用context传递span信息。现在开始在grpc请求中实现简单的grpc-jaeger-demo,spa...

2019-02-28 21:07:45 32589

原创 golang实现简单的jaeger-demo

参考地址:https://github.com/yurishkuro/opentracing-tutorial/tree/master/gojaeger是一个比较有名的分布式链路追踪系统,底层用golang实现,兼容opentracing标准,这里利用其go-client来实现一个最简单的demo,仅供参考。1. 安装必要的包:"github.com/opentracing/open...

2019-02-26 13:25:42 36825 1

原创 用golang实现替换某个文件中的字符串

用golang实现了某个文件中字符的替换,替换为按行替换,执行后会生成新文件,如a.txt,执行后生成a.txt.mdf。新文件即修改后的内容。主要用来练习文件的读取与写入。package mainimport ( "bufio" "fmt" "io" "os" "strings")func main() { if len(os.Args) != 4 { fmt...

2019-02-25 20:31:37 43013 2

原创 golang实现延时队列

github源码地址:https://github.com/hackssssss/delay_queue参考了有赞延时队列的设计思路,自己写了一个延时队列,基本原理是利用redis的list实现队列,利用redis的zset实现按照时间排序功能。大体流程如下图所示:流程解读:1. 调用方调用Push接口,将data、ttr(time to return)、notify_url传...

2019-02-18 20:10:09 33084 1

原创 golang slice在其他函数中修改,易错点

回忆起写golang时候踩过的坑,那是我逝去的青春……我们可能会遇到给其他函数传递一个slice,让其他函数给这个slice做一些修改的情况。想到slice是引用传递,可以直接传递slice用作修改,于是可能出现下面这种情况:package mainimport ( "fmt" "testing")func TestModifySlice(t *testing.T) { ...

2019-02-06 13:33:54 33489

原创 golang获取本月第一天、获取本月最后一天、获取当天0点的时间

 主要是通过time.Now()函数和time.AddDate函数以及time.Date()函数来构造和加减日期,获取本月第一天和最后一天。具体可以看代码实现。package utilimport ( "time")//获取传入的时间所在月份的第一天,即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。func GetFirstDateOfMonth(...

2019-02-05 19:27:56 50210

原创 用户签到的数据库设计方案

初步设计了一下用户签到的设计方案,记录下这种思路,以后可能需要完善。每月最多有31天,int32有32位,签到与没签到只有两种状态,签到用1来表示,未签到用0来表示,因此可以用int32来表示用户每月的签到情况。数据库表(sign_record)的设计:列 类型 描述 id int64 自增键 user_id int64 索引,用户表的id ...

2019-02-01 13:21:15 47646 14

原创 redis过期策略

最近在读redis深度历险,记录一下在读书的过程中一些重要的知识点,供以后查阅。redis过期策略有两种,一种是主动式过期,另一种是被动式过期,redis采用两者相结合的方式来处理,因为单纯采用主动式过期,会影响redis的性能,单纯采用被动式过期,可能会导致大量内存得不到释放。主动式过期:    redis会将所有设置了过期时间的key放到一个独立的字典中,以后会定时扫描这个字典,将...

2019-01-29 12:46:14 29900

原创 leetcode128. Longest Consecutive Sequence 最长连续序列 并查集

题目地址:https://leetcode.com/problems/longest-consecutive-sequence/方法1:并查集这个题的难点在于当更新了某个val后,不能及时更新val周围连续的数值,如val+1, val+2, val-1, val-2等。这里采用并查集的思想,将每一段连续的数值,看做是一个集合,每个集合中有一个leader或者parent。当val值有更新...

2019-01-02 20:28:31 428

原创 golang去除排序数组中的重复值 leetcode. Remove Duplicates from Sorted Array

题目地址:https://leetcode.com/problems/remove-duplicates-from-sorted-array/去除排好序数组中的重复元素,这里利用一个index j来确定每个不重复元素“应该在的位置”,遍历整个数组,当这个元素与前一个元素相等时,那么j不移动,表明下一个不重复元素应该在这里。当前元素与前一个元素不相同时,当前元素移动到j的位置,j++。具体的...

2018-12-29 18:32:05 1025

原创 leetcode. Longest Common Prefix最长公共前缀

题目地址:https://leetcode.com/problems/longest-common-prefix/需要找到给定字符串数组中所有字符串的最长公共前缀,开始想的是用min个map来存储这些字符串,min是数组中最短字符串的长度,map的key是字符,value是字符出现的次数。遍历数组中的每个字符串,将每个字符添加到对应的map中,如字符串中第i个字符,添加到第i个map中。最...

2018-12-29 18:23:18 175

原创 golang expired LRU cache(key有过期时间的,实现了LRU算法的cache)

github地址:https://github.com/hackssssss/lru_expired_cache之前实现了lru算法的cache,链接,后来发现可以添加key自动过期的策略,采用惰性过期策略。即当get或者set这个key时,才去更新key的状态,如果过期,那么将其删除。package lru_expiredcacheimport ( "container/list...

2018-12-29 17:25:00 2458

原创 golang LRU Cache

github地址:https://github.com/hackssssss/lruCache用golang中的map与list双向链表实现了lru(最久未使用)算法,map value中存放数据以及key在list中的地址,list中存放map的key,当set或者get时,从map中获取key在list中的地址,将其删除(list是双向链表,删除复杂度O1),并在list尾部添加新的key...

2018-12-28 17:46:01 28903

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除