自定义博客皮肤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

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

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

原创 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 111

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

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

2021-08-04 17:52:25 200

原创 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 174

原创 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 910

原创 golang常驻后台类worker模板

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

2020-08-28 13:54:45 386

原创 使用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 2001

原创 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 688

原创 Kubernetes Controller Manager原理浅析
原力计划

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

2020-05-08 14:39:42 630

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

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

2020-04-02 18:37:13 2388 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 1120 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 1650 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 1143

原创 grpc复用client连接

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

2019-09-17 15:18:30 6411

原创 golang实现简单的goroutine worker池

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

2019-09-05 20:33:39 394

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

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

2019-05-08 19:45:57 1838

原创 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 4535

原创 golang利用redis实现限速器

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

2019-05-05 21:11:21 1612

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

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

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

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

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

2019-05-04 18:42:52 167

原创 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 2843

原创 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 2872 2

原创 漏桶算法

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

2019-03-12 21:06:36 1597

原创 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 31305

原创 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 34404

原创 用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 39681 1

原创 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 31965 1

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

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

2019-02-06 13:33:54 31084

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

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

2019-02-05 19:27:56 41501

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

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

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

原创 redis过期策略

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

2019-01-29 12:46:14 29725

原创 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 316

原创 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 713

原创 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 112

原创 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 1409

原创 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 28690

原创 golang实现expiredMap,key带过期时间,超时自动删除

github地址:https://github.com/hackssssss/ExpiredMap偶然间看到一篇关于超期删除key的map的文章,感觉很有意思,于是自己去实现了一下。了解了一下redis中key的过期策略,发现主要有三种策略:一种是被动删除,即key过期之后,先不将其删除,当实际访问到的时候,判断其是否过期,再采取相应的措施。第二种是主动删除,即当key过期之后,立即将这个...

2018-12-26 12:40:14 5585 1

原创 敏感词过滤golang

 用golang写了敏感词过滤的工具,主要用来检测用户昵称中是否存在敏感词,同时提供剔除转移字符的功能。可以先将敏感词库存放在一个map中,敏感词可以参考这里:https://github.com/fwwdn/sensitive-stop-words将map和昵称传入,程序会检查昵称的每一个子串,判断是否在map敏感词库中。复杂度O(len(name)^2)package util...

2018-12-21 12:40:02 30488

原创 golang删除slice中特定条件的元素,优化版

写了两种对一个slice中删除特定元素的方法,并做了性能对比,在这里记录一下。第一种方法:func DeleteSlice(a []int) []int{ for i := 0; i &lt; len(a); i++ { if a[i] == 0 { a = append(a[:i], a[i+1:]...) i-- } } return a}解释:这里利...

2018-12-20 19:56:28 20557 15

原创 golang线程安全的map

github地址:https://github.com/hackssssss/safemap网上找的协程安全的map都是用互斥锁或者读写锁实现的,这里用单个协程来实现下,即所有的增删查改操作都集成到一个goroutine中,这样肯定不会出现多线程并发访问的问题。基本思路是后台启动一个长期运行的goroutine,阻塞的接受自己channel中的请求req,req分为不同的请求,比如读key...

2018-11-19 20:37:09 30288

原创 golang支付宝支付生成签名

调用支付宝支付接口时,需要用商户自己的私钥生成sign,将数据与sign一起发送给支付宝来发起支付。这里总结一下签名的流程,以支付宝手机网站支付为例。实现语言为golang。请求参数网址:https://docs.open.alipay.com/203/107090/一. 生成biz_content业务参数信息:func GenBizContent(subject, outTra...

2018-11-08 11:21:43 31548

空空如也

空空如也

空空如也

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

TA关注的人 TA的粉丝

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