- 博客(78)
- 资源 (9)
- 问答 (7)
- 收藏
- 关注
原创 使用 redis scan 踩了大坑记录
业务中有一个需求需要将数据先缓存到redis中以应对高并发的问题,然后后台定时的去将这些数据落盘mysql,叮叮当当的开发自测完成,经过测试大佬对业务功能测试和压测通过后,就马不停蹄的上线了,然而,刚上线不久,就发现服务cpu和内存占用持续升高,但没有达到100%,一只保持较高的水平。经过对服务pprof采集分析,发现居然是这个需求代码中的定时任务占用了大量的cpu占用。
2022-10-29 17:17:41
405
1
原创 Go AOP注解实现开源框架
记录Go相关开源AOP实现框架基于ast语法解析和monkey动态代理实现类似Java的注解,提供事务注解demo: https://github.com/handsomestWei/go-annotation【易懂】开课啦教育公司相关同学写了一个扫描代码的工具,在每个 RPC 服务方法前加上对应的注释,从而在服务启动前通过扫描注释生成元数据https://github.com/jack15083/dubbo-go-proxy-tool【秀】golangAnnotations工具将go
2021-11-07 22:19:35
1588
原创 怎么查看Go中全局变量存储的位置?
创建main.gopackage mainimport "fmt"var xxx = 0xEE // 通过值来推断类型var yyy int = 0xFF // 定义类型,并赋值var zzz int // 定义变量var ddd *intfunc main() { xxx = 0x11 yyy = 0x22 zzz = 0x33 k := 10 ddd = &k fmt.Println(xxx, yyy, zzz)}
2021-11-07 16:15:59
924
原创 Go ants中的指数退避算法抢锁技巧
首先看一下指数退避算法的维基百科解释看不了的直接看图片吧在go 协成池框架中有一把巧妙的锁:spinLockimport ( "runtime" "sync" "sync/atomic")type spinLock uint32const maxBackoff = 64func (sl *spinLock) Lock() { backoff := 1 // 巧妙之处 for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1)
2021-10-22 22:02:29
638
原创 Go 指针陷阱
Go 指针陷阱uintptr被GC当做普通整数对象,不会阻止所“引用”的对象被回收package mainimport ( "time" "unsafe")type data struct { x [1024 * 100]byte}func test() uintptr { p := &data{} return uintptr(unsafe.Pointer(p))}func main() { const N = 10000 cache := new([N]ui
2021-10-21 12:35:53
671
原创 Go汇编入门资料【强!!!】
1. 汇编角度看go2. 《plan9 汇编入门,带你打通应用和底层》讲义3. 《plan9 汇编入门,带你打通应用和底层》视频地址【这B站里面有很多Go夜读活动视频可以学习】4. 曹大go源码阅读5. 曹大源码阅读【汇编篇】6. 曹大博客7. 字节开源性能强悍的工具库,里面用了不少汇编go tool compile -S生成的汇编代码中,常见的寄存器解释如下:PC:程序计数器,指下一步要执行的程序,伪寄存器PC和硬件寄存器PC作用差不多。SP:指向当前栈帧的栈顶。但是生成的汇编代码中都
2021-10-11 22:56:15
763
原创 SI-MQTT集群消息处理
SI-MQTT MQTT v5 Broker此si-mqtt提供了一种比较开放的集群消息处理方式:集群消息发送只开放一个方法,负责发送publish、subscribe、unsubscribe msg.// SendMsgToCluster 发送消息到集群// shareName 共享主题组// targetNode 目标节点// 这两个参数用于集群共享主题消息发送到特定的节点func SendMsgToCluster(msg messagev5.Message, shareName, t
2021-10-02 16:42:43
1006
原创 Go易产生的并发Bug记录
参考地址:https://gocn.vip/topics/125291. 该 bug 来自 etcd 项目,由于误用 WaitGroup 导致的非阻塞 bug1 func(p *peer) send() {2 p.mu.Lock()3 defer p.mu.Unlock()4 switch p.status {5 case idle:6 + p.wg.Add(1)7 go func() {.
2021-09-09 09:34:14
890
原创 Redis各种数据类型最多可以存多少数据
redis官方文档Strings类型:一个String类型的value最大可以存储512MLists类型:list的元素个数最多为2^32-1个,也就是4294967295个。Sets类型:元素个数最多为2^32-1个,也就是4294967295个。Hashes类型:键值对个数最多为2^32-1个,也就是4294967295个。Sorted sets类型:跟Sets类型相似。分享方案Redis百亿级Key存储方案...
2021-08-27 17:01:39
12368
原创 GO项目性能优化大赏
本文旨在记录工作、学习过程中遇到的性能优化技巧,会不停的添加内容常规手段1.sync.Pool临时对象池应该是对可读性影响最小且优化效果显著的手段。基本上,业内以高性能著称的开源库,都会使用到。最典型的就是fasthttp了,它几乎把所有的对象都用sync.Pool维护。但这样的复用不一定全是合理的。比如在fasthttp中,传递上下文相关信息的RequestCtx就是用sync.Pool维护的,这就导致了你不能把它传递给其他的goroutine。如果要在fasthttp中实现类似接受请求-&g.
2021-08-27 12:51:19
1487
原创 //go:开头的注释学习
看go源码时,会经常看到很多这种 go:xxx 的注释//go:linkname reflect_typehash reflect.typehash//go:noescape//go:nosplit//go:nowritebarrierrec//go:yeswritebarrierrec//go:noinline//go:norace通过网上冲浪收集整理的知识如下://go:linkname localname [importpath.name]使用[importpath.name]
2021-08-20 11:50:18
1182
原创 SI-MQTT-v5版协议报文编解码实现
MQTT 控制报文编解码实现初版,还有许多协议细节未处理,正在完善中,欢迎共同参与有错误欢迎指出修改哦connectconnackpublishpubackpubrecpubrelpubcompsubscribesubackunsubscribeunsubackpingreqpingrespdisconnectauth...
2021-08-19 11:19:22
943
原创 MQTT协议之剩余长度编解码算法实现
MQTT协议中,剩余长度使用的是一种变长度的编码方案,其剩余长度 = 可变报头长度 + 负载长度。所以剩余长度最少占用1个字节,最多占用4个字节。下图就是MQTT协议中总结的剩余长度不同的取值范围,对应所占用的字节数。而这些范围对应到具体数据的编解码由下面的算法来实现。下图是从MQTT协议中copy的其编码解码算法MQTT采用大端序列传输数据,想知道自己计算机是大端还是小端可以通过一个int64的数据1,左移大于32位,强转为byte,看看是0还是大于0的,是0就是大端的一个字节包含8
2021-08-07 09:48:29
1192
原创 Golang:MQTT服务集群共享主题设计【通配符实现篇】
接上篇的初步思路,可以通过这样的方式获取所有的需要匹配的订阅主题接下来实现一波// 获取需要匹配的主题,简单方式,没有考虑性能了,怎么简单怎么来// 下面可优化的地方太多了,性能不是很好func matchTopicS(topic string) []string { tp := strings.Split(topic, "/") ret := list.New() ret.PushBack(tp[0]) // 直接限制订阅主题第一个不能是通配符,并且不能是单纯一个/,所以该方法就.
2021-04-08 00:09:04
1295
1
原创 Golang:MQTT服务集群共享主题设计
前言:本次设计的支持集群的共享订阅的思路,还存在缺陷,无法支持通配符订阅,正在努力实现中,敬请期待,或者有好的点子,欢迎分享哦,谢谢各位。具体实现用在了该项目中集群共享订阅单机共享订阅是非常容易实现的,代码改动也比较小,但是我们今天的角色不是单机的共享订阅,而是集群的我们采用一个简单的方式来实现部分功能,使用redis的set+hash具体结果如下图:订阅主题订阅主题时,需要一条lua脚本向redis中操作两个key,分别操作数据set 的key中往topic key中添加该shar
2021-04-03 22:14:39
2314
2
翻译 Golang:Go 网络包默认值下的陷阱
Go 网络包默认值下的陷阱超时时间HTTP响应主体HTTP / 1.x保持活动连接池验证URIDNS缓存伪装的DualStacknet.Dial()错误net.IP 是可变的奖励:GOMAXPROCS,容器和CFS超时时间设置它们!网络不可靠,并且标准库默认客户端和服务器未设置其主要超时,并且所有这些都将零值解释为引导的无穷大。超时取决于用例,Go核心团队已避免进行任何笼统的概括。注意:这也包括对包级别便利功能的所有使用: http.Get客户端朋友http.ListenAn
2021-03-31 22:24:25
1433
转载 Golang:深入理解 errgroup
深入理解 errgroup原文,此处只是做记录学习使用前言我们平时使用go来并发操作时,在主协程需要等待其他协成完成后才会继续执行的情况,我们会使用sync.WaitGroup 来进行操作。在一个 goroutine 需要等待多个 goroutine 完成和多个 goroutine 等待一个 goroutine 干活时都可以解决问题。虽然 WaitGroup 已经做了很好的封装,但是仍然存在一些问题,例如如果需要返回错误,或者只要一个 goroutine 出错我们就不再等其他 goroutin
2021-03-31 22:20:46
713
翻译 Golang:Go如何知道time.Now的时间
Go如何知道时间。大约时间首先,它是非常有用的了解。该time.Time结构可以表示具有纳秒精度的时间瞬间。为了更可靠地测量经过的时间以进行比较,加法和减法,time.Time还可以包含当前过程单调时钟的可选的,纳秒级精度的读数。这是为了避免报告错误的持续时间,例如。如果是DST。type Time struct { wall uint64 ext int64 loc *Location}imeime结构在2017年初采用了这种形式。您可以浏览Russ Cox自己浏览的相关问题,建议和
2021-03-31 22:10:10
1378
原创 Golang:监听binlog日志
package binlog_testimport ( "fmt" "github.com/json-iterator/go" "github.com/siddontang/go-mysql/canal" "github.com/siddontang/go-mysql/schema" "reflect" "runtime/debug" "strings" "testing" "time")func TestBinLog(t *testing.T) { go binLogList
2021-03-26 09:46:22
2879
原创 Golang:请求合并
请求合并学习golang.org/x/sync/singleflight的代码记录// 请求合并package req_mergeimport ( "errors" "fmt" "runtime" "sync")type Group struct { sync.Mutex m map[string]*call}// 每个相同请求的回调type call struct { wg sync.WaitGroup val interface{} // 函数返回值,只会写入一次,
2021-03-24 13:00:51
1229
原创 QUIC协议试触-节点通信协议参考
从某歌网站了解到,QUIC协议可能会成为未来的HTTP3协议的方向,这是一个使用UDP协议来达到TCP的效果,甚至某些方面更优,但是这家伙是以UDp为基础的,还是会存在UDP的一些不足,比如:安全问题,也就是反射攻击,即伪造原地址;还有就是这些年性能的优化提升都几乎针对 TCP ,使得 UDP 性能没有啥改进。当然随着 QUIC3 的发布,相信后续应该会有相对的投入。想利用该协议来实现节点间数据通信,顾实验一番,下面有啥错误的地方,一定要指出来哦,感谢大家:我是使用了这个go库来玩的:github.c
2021-03-07 22:32:38
1142
原创 Golang:运行时动态生成你想要的Struct
package my_structimport ( "errors" "reflect")// 构造器type Builder struct { // 用于存储属性字段 fileId []reflect.StructField}func NewBuilder() *Builder { return &Builder{}}// 添加字段func (b *Builder)AddField(field string,typ reflect.Type) *Builder {
2021-02-26 00:08:17
6069
5
原创 Golang: 高效截取的字符串
当我们需要从一串很长的字符串中获取一部分时,是不是有点恼火,特别是有中文在里面的时候,就是那些一个字符占几个字节的数据。字节切片截取的方式我们可能会常做的事就是像这样:s := "abcdefghijk"fmt.Println(s[1:4])这样获取字符串部分数据傻没毛病,正常情况下,golang中字符串是不变的,我们直接采取这种方式可以达到我们的目的。我们知道这是按字节截取,在处理 ASCII 单字节字符串截取,没有什么比这更完美的方案了,但是当我们的字符串中出现了中文数据,中文往往占多个字
2021-02-25 20:48:26
4008
原创 Golang:atomic包怎么对uint64/uint32进行减法
学习atomic包时,发现一个有趣的东西:unsafe.Pointer类型,该包并未提供进行原子加法操作的函数。uint*类型怎么做减法运算?我们来看第2点:var a int64 = 10atomic.AddInt64(&a,-3)fmt.Println(a)结果很明显是:7但是当我们对uint*进行减法运算时:var b uint64 = 10atomic.AddUint64(&b,-3)fmt.Println(b)直接这样写会使 Go 语言的编译器报错,
2021-02-23 21:59:23
2845
1
原创 怎样学好Java反射?
以下为我平时的学习记录,有不对的地方,一定要指出哦。一、开场白反射是一个非常重要的知识点,在学习Spring、SpringBoot框架时,Bean的初始化,切面编程,破坏单例模式时,获取标注的注解时等等,我们都会用到反射。在现在面试造火箭,工作拧螺丝的招聘场景中,反射是一个非常热点的话题,当我们看了很多的开源框架源码时,就会经常发现里面有用到反射的地方。今天主要聊一下反射的相关概念、应用以及反射的性能!二、反射是啥?我们平时创建一个Java对象的时候,最最最常用的应该就是new 对象()了,这.
2020-10-13 13:29:23
237
2
原创 细节决定成败(二)
细节决定成败(二)怎么在不使用“+”的情况下,对两个数进行相加public int plus(int a,int b){ //两个临时变量 int aTemp = 0,bTemp = 0; while(b!=0){ aTemp = a ^ b; btemp = (a & b) << 1; a = aTemp; b = bTemp; } return a;}那如何在不创建临时
2020-10-10 09:46:42
225
原创 来一套通用分布式幂等组件不咯!
通用分布式幂等组件之前一篇文章中提到了幂等性的一些解决办法,但是基本上是单机上的,今天我们来弄一个支持分布式的通用幂等性组件【以下有不对的地方,一定要指出哦,共同成长。】一、背景分布式系统由众多微服务组成,微服务之间必然存在大量的网络调用。比如一个服务间调用异常的例子,用户提交表单之后,请求到A服务,A服务落单之后,开始调用B服务,但是在A调用B的过程中,存在很多不确定性,例如B服务执行超时了,RPC直接返回A请求超时了,然后A返回给用户一些错误提示,但实际情况是B有可能执行是成功的,只是执行时间过
2020-10-08 22:03:13
1388
原创 为什么不建议在循环体中使用+进行字符串拼接?
为什么不建议在循环体中使用+进行字符串拼接?最近复习一下了阿里Java开发规范,并记录一下。我们首先来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率如何吧(jdk1.8)public class StringBuilderAndAdd { public static void main(String[] args) { long s1 = System.currentTimeMillis(); new StringBuilder
2020-09-27 18:30:38
479
原创 SpringCloud中Hystrix选择线程池进行隔离时导致的ThreadLocal数据丢失的解决方法参考
SpringCloud中Hystrix选择线程池进行隔离时导致的ThreadLocal数据丢失的解决方法当我们在SpringCloud中选择Hystrix来实现断路器,Zuul中默认是用信号量,而Hystrix默认是线程池来进行隔离的。当使用线程隔离时,会有一个很重要的问题需要注意:那就是在一些业务场景下,可能需要ThreadLocal里在线程里传递数据,当然,如果你使用信号量的话是没问题的(信号量,请求进来的时候,以及后续的处理都是通过一个线程,这个是没问题的)。当隔离模式选择了线程池时,H
2020-09-24 13:09:15
1776
原创 GoMQTT服务器 节点路由树设计
GoMQTT服务器 节点路由树设计第一章 节点路由树设计文章目录GoMQTT服务器 节点路由树设计思路一、节点路由树设计二、代码1. 主题节点添加与删除总结思路采用节点路由树来管理mqtt消息需要发送到哪些节点上去,当该节点有消息需要转发到其他节点时,查找该表,得到需要转发的节点信息,再转发。当然,可以为了性能优化:不一定有通配符和没有通配符都采用路由树,可以通过对没有通配符的主题进行hash,来查找相应的节点,这个需要仔细考虑一下,我暂时只是有这个想法。添加节点到主题上去,采用对应的主
2020-09-09 18:20:04
1115
原创 GoMQTT服务器 tcp处理粘包问题
GoMQTT服务器 tcp处理粘包问题第一章 tcp处理粘包问题写的不好,请指出,目前还在学习当中文章目录GoMQTT服务器 tcp处理粘包问题前言一、问题显示1.服务器代码2.客户端代码3.问题二、分析1.为什么会出现粘包2.解决办法编解码修改服务端代码修改客户端代码服务端接收数据效果前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例
2020-09-04 13:45:07
1617
原创 细节决定成败(一)
ScheduledThreadPool 执行周期性任务,假设某次出现了异常,周期任务还会继续吗?查看ScheduledExecutorService接口里的scheduleWithFixedDelay方法的jdk文档,有描述如下: If any execution of the task encounters an exception, subsequent executions are suppressed. 如果在任务的执行中遇到异常,后续执行被取消。 ScheduledThreadPoolExecu
2020-08-12 14:19:47
718
原创 Ubuntu18安装部署Kubernetes并完成Nginx-deployment的安装、升级、扩容、删除操作demo
Ubuntu18安装部署Kubernetes并完成Nginx-deployment的安装、升级、扩容、删除操作demo【采用docker方式进行】【1】在虚拟机安装kuberctl1.下载最新版:curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/lin
2020-07-29 14:37:40
1868
原创 JVM-方法内联
JVM-方法内联jvm学习记录方法内联(inlining,对性能的提升很大):方法内联可以减少方法调用,从而减少方法栈的创建。简单点说:就是把被调用方函数代码"复制"到调用方函数中,减少因函数调用开销的技术。相信大家都知道循环的速度比递归快很多,就是这个原因,另外方法内联后,还使得一些JIT更深入的优化变成可能。jvm可以通过两个启动参数来控制字节码大小为多少的方法可以被内联:-XX:MaxInlineSize: 能被内联的方法的最大字节码大小,默认值为35Byte,这种方法不需要频繁的调用。比
2020-07-26 09:45:15
1707
原创 JVM-逃逸分析
JVM-逃逸分析这个可以从一个问题入手:Java中的对象都是在堆中分配吗?说明为什么!这个很明显,稍微会点JVM知识的人都会知道,但是JVM是怎么来判断是否应该在堆上分配还是其它地方分配?主要有这两种逃逸情况,我们来聊一聊。方法逃逸线程逃逸1.什么是逃逸分析技术逃逸分析: 就是分析Java对象的动态作用域,如果在一个方法内创建了一个对象,而且外部对象能够引用到这个对象的话,这就是方法逃逸 (作用域逃出了这个方法) ,如果能够被其它线程使用到的话,这就是线程逃逸(作用域逃出了这个线程)
2020-07-25 22:13:43
910
STM32F407ZG_OLED_DHT11_esp8266_光敏.rar
2020-10-30
stm32+wifi+dht11+oled+web数据展示.rar
2020-06-09
Go 常用的接口断言操作 !
2021-06-24
如果要对原子值和互斥锁进行二选一,最重要的三个决策条件应该是什么?
2021-02-23
TA创建的收藏夹 TA关注的收藏夹
TA关注的人