自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

程序猿的世界

「WHY」每一个你不满意的当下,都有一个你不曾努力的过去。

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

原创 GoLang开源微服务框架

https://github.com/air-go/rpc

2020-07-07 14:59:50 1420

原创 GoLang 的锁“失效”

GoLang 的锁“失效”和 noCopy

2022-09-28 10:35:31 589 1

原创 GoLang 单元测试打桩和 mock

单元测试,顾名思义对某个单元函数进行测试,被测函数本身中用到的变量、函数、资源不应被测试代码依赖,所谓 mock,就是想办法通过 “虚拟” 代码替换掉依赖的方法和资源,一般需要 mock 掉以下依赖:变量函数/方法MySQLRedishttp 调用。

2022-09-06 20:14:43 4555 2

原创 Go1.18 新特性 — 泛型、Fuzzing、work工作区

本文源码:https://github.com/why444216978/go1.18-features-demoFuzzing Fuzzing,又叫 fuzz testing,中文叫做模糊测试或随机测试。其本质上是一种自动化测试技术,更具体一点,它是一种基于随机输入的自动化测试技术,常被用于发现处理用户输入的代码中存在的bug和问题。 在具体实现上,Fuzzing不需要像单元测试那样使用预先定义好的数据集作为程序输入,而是会通过数据构造引擎自行构造或基于开发人员提供的初...

2022-03-16 15:57:49 1704

原创 深入理解高性能字节池 bytebufferpool

字节池 bytebufferpool 源码剖析

2021-12-18 20:12:03 1163

原创 深入理解 errgroup,并实现服务优雅关闭和资源回收

发现问题GoLang 为我们提供了 WaitGroup 用来解决当前 goroutine 等待多个 goroutine 结束的问题,但是当我们需要获得协程返回的错误,则无能为力。解决问题为解决上面的问题,官方为我们提供了 errgroup 包,支持返回 goroutine 遇到的第一个错误// Group 等待组结构体定义type Group struct// WithContext 根据传入的ctx返回Group和新的ctxfunc WithContext(ctx conte

2021-11-28 16:53:25 796

原创 连接多路复用,同一个端口同时提供 HTTP 和 gRPC 服务

$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protoc-3.17.3-linux-x86_64.zip$ unzip protoc-3.17.3-linux-x86_64.zip$ cp ./protoc/bin/protoc $GOROOT/bin/or$ wget https://github.com/protocolbuffers/protobuf/releases/dow...

2021-09-20 21:22:10 2636

原创 MySQL源码调试,一条最简单的select语句是如何执行的?

码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071,或关注公众号:程序猿AirGo注意:我们当前是以8.0.18为准,调试时需要注意版本对应的行数问题。安装MySQL1、下载linux通用源码:wgethttps://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.18.tar.gz2、解压压缩包:tar -zxvf mysql-8.0.18.tar.gz3、安装依赖工具:yum/brew ...

2021-08-22 20:09:36 1578

原创 基于 Docker 搭建 etcd 集群和命令权限管理

下载安装$wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz$tar xf etcd-v3.5.0-linux-amd64.tar.gz$cd etcd-v3.5.0-linux-amd64打包镜像编写 Dockerfile:FROM alpineADD etcd /usr/local/bin/ADD etcdctl /usr/local/b

2021-08-20 17:11:19 1097

原创 高并发下的缓存问题,这篇就够了

缓存 缓存大家都不陌生,目的是为了优化磁盘数据读取的性能问题,缓存 + DB 的架构往往如下如图所示: 但是,缓存也是一把双刃剑,用好了可以让服务性能大幅度提升,用不好,就可能为系统埋下隐患。本文就从缓存最常见的几个问题出发,讨论一下每种问题的解决方案。目前最常用的分布式缓存数据库就是 Redis 了,所以本文代码实例均以 Redis 为准。缓存雪崩 缓存目的是为了解决热点数据的访问,所以当某些数据一段时间没有被访问时,缓存会过期自动失效,假想一下...

2021-08-15 21:42:52 864

原创 我用四种设计模式进行抽象,解决了N家资源方接入问题

需求场景 场景是这样的,我们的业务是医疗场景下的问诊业务,具体场景包括在线咨询和线上复诊,每个场景都分为免费和付费,也就是一共 4 个业务流程,并且相互之间有很大一部分流程相同,但又在部分流程中有或多或少的区别。同时,需要对接医院 HIS 系统的挂号服务,并且每家医院的挂号流程均不相同,比如有些需要手动开收费项来收取挂号诊查费,有些是免费。难点和方案 上面的需求,总结下来就是要求我们的系统需要同时支持 4 种业务流程,且兼容多家 HIS 系统,翻译成代码层面,就是下面几点...

2021-08-07 15:23:43 514

原创 从0到1手撕负载均衡算法

轮询package mainimport ( "fmt" "sync/atomic")var ( nodeAddress = map[string]string{ "A": "127.0.0.1", "B": "127.0.0.2", "C": "127.0.0.3", "D": "127.0.0.4", } nodeIndex = []string{"A", "B", "C", "D"} nodeWeight = map[string]i...

2021-07-17 17:42:35 470 1

原创 MySQL效率提升大杀器 — Change Buffer

目录为何慢Change Buffer​处理流程InsertDeleteUpdate内部实现非叶子节点Insert Buffer BitmapMerge处理辅助索引被读取辅助索引页已无可用空间Master Thread 定时 Merge相关配置innodb_change_buffer_max_sizeinnodb_change_buffering适用场景为何慢 大家在面试中应该都会遇到这样一个问题:索引建多了有什么坏处?相...

2021-07-06 12:42:45 628 1

原创 微服务注册中心和三种服务发现模式

为何需要在我们日常开发中,需要调用另一个服务时,一般都是通过 API 接口发送请求,解析响应,再处理后续的业务逻辑,在这个过程中有没有思考过下面这些问题:如果我们调用的某个下游服务某个节点挂了,该怎么办? 调用方如何确定调用的是哪个节点? 下游服务进行上线操作时,如何保证上游能够正常调用? K8s 集群内节点的网络地址都是动态分配的,上游调用时如何找到新上线的节点?我们今天的主角,注册中心提供的服务发现能力,就可以解决上述问题。...

2021-04-10 15:18:01 1341

原创 GoLang通过gRPC流处理实现发布订阅服务

目录流式处理服务端流式客户端流式双向流式发布订阅服务pubsub原理代码实现gRPC代码服务端代码订阅端代码发布端代码流式处理所谓流式处理,就是客户端和服务端一方可以源源不断地发送请求,另一方按照发送顺序依次处理请求。流式 RPC 分为三种,分别是服务端流式、客户端流式、双向流式服务端流式客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取直到没有更多消息为止。rpc Hello (HelloRequ

2021-03-21 18:53:36 2323

原创 初探 gRPC 和 proto import

安装命令go get google.golang.org/protobuf/cmd/protoc-gen-go go get google.golang.org/grpc/cmd/protoc-gen-go-grpc编写proto文件语法参考:https://www.jianshu.com/p/da7ed5914088syntax = "proto3";package pb;message Request { string Name = 1;}message Re

2021-03-18 01:46:32 1155

原创 GoLang源码系列之:通过一个最简单的RPC服务探究net/rpc源码实现

前言之前做的服务大多基于 HTTP 实现服务端和客户端,可以通过 API 接口的方式进行调用,优点是不受语言限制、调用方便。但是众所周知 HTTP 是应用层协议,所以对于性能要求较高的服务来说,更适合用基于 TCP 的 RPC 服务。由于最近在转 Go 语言,标准库提供了开箱即用的 RPC 包,之前一直没接触过,最近正好打算学习 RPC,所以通过一个最简单的 RPC 服务来研究了下 net/rpc 包的实现原理。示例代码例子非常简单,客户端发送一个字符串,服务端返回 hello + 字符串作为.

2021-03-14 23:21:50 1005

转载 关于TCP半连接队列和全连接队列

前言网上许多博客针对增大 TCP 半连接队列和全连接队列的方式如下: 增大 TCP 半连接队列的方式是增大 /proc/sys/net/ipv4/tcpmaxsyn_backlog; 增大 TCP 全连接队列的方式是增大 listen() 函数中的 backlog; 这里先跟大家说下,上面的方式都是不准确的。“你怎么知道不准确?”很简单呀,因为我做了实验和看了 TCP 协议栈的内核源码,发现要增大这两个队列长度,不是简简单单增大某一个参数就可以的。

2021-02-23 11:37:40 334

原创 搞不懂协程的同步控制,千万别说自己会GoLang

前言Go 语言提供了协程并发编程模型,那么只要是并发就需要解决协程间同步问题,官方为我们提供了同步工具,sync 包。性能测试参考:https://success.blog.csdn.net/article/details/112339434锁的使用锁有如下特点,使用时需要注意:锁在 Go 语言中都是成对出现的,也就是说每一个加锁操作必须要对应一个解锁操作,我们通常会跟一个 defer 语句进行解锁。 对已锁的锁再次加锁会阻塞当前加锁协程 对未锁定的锁进行解锁会触发 panic,且无

2021-02-11 11:25:39 868 3

原创 Vim打造成GoLang开发环境

源码安装GoLang进入:https://golang.google.cn/dl/下载:wgethttps://golang.google.cn/dl/go1.14.6.darwin-amd64.tar.gz安装:tar -C /usr/local -xzf go1.14.6.linux-amd64.tar.gz配置环境变量:vim ~/.bash_profileexport GOROOT=/usr/local/goexport GOPATH=/Users/why/Desktop..

2021-01-09 12:51:58 4445

原创 GoLang测试那些事儿

码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071单元测试测试命令单用例命令行打印html直观展示多用例(Table-Driven Test)goconvey测试工具基准测试Example测试预告PS:本文中用到的所有 go 生态工具(go test、gotests、goconvey),均未介绍安装过程,请自行百度。单元测试testing为 Go 语言 package 提供自动化测试的支持。通过go tes...

2021-01-07 23:15:41 1405

原创 GoLang性能分析利器:pprof

查看命令帮助:go tool pprof -help进入命令交互:通过正在运行的程序取样保存成文件,再进入命令交互:# 下载 cpu profilego tool pprof http://47.93.238.9:8080/debug/pprof/profile\?seconds=10 # 下载 heap profilego tool pprof http://47.93.238.9:8080/debug/pprof/heap\?seconds=10 # 下载

2021-01-06 15:58:01 743 1

原创 GoLang协程原理解读,收藏作为面经再合适不过了

线程实现模型 在操作系统提供的内核线程之上,Go 搭建了一个特有的用户级线程模型。传统的函数调用是将函数指针存储在内存的栈空间上,但是栈空间只允许操作系统进行操作,我们能拿到的只限于堆内存,所以 Go 开发者在堆上申请一块内存,将寄存器 %rsp 以及寄存器 %rbp 指过去,从而将这块内存伪装成用户栈,从而巧妙地实现了并行运行用户级线程 goroutine。要聊 Go 的线程实现模型,必须要知道以下3个核心元素:M:machine 缩写,一个 M 代表一个内核线程。 P:proces...

2020-12-28 20:35:10 1401

原创 GoLang使用Goroutine+Channel实现流水线处理,扇入扇出思想解决流水线上下游供需不平衡

package mainimport ( "fmt")func buy(n int) <-chan string{ out := make(chan string) go func(){ defer close(out) for i := 1; i <= n; i++{ fmt.Println("buy", i) out <- fmt.Sprintf("配件%d", i) } }() return out}func build(in &lt.

2020-12-24 19:56:04 883 2

原创 GoLang中结构体的深拷贝和浅拷贝

先看几个完整的例子:func DeepCopy(dst, src interface{}) error { var buf bytes.Buffer if err := gob.NewEncoder(&buf).Encode(src); err != nil { return err } return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)}type User struct { Name strin

2020-12-15 20:43:30 3546

原创 Go接口中的值接收者和指针接收者

码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071先说结论:在实现接口时,应保持接收者定义、结构体定义、断言类型一致等价场景当方法的接收者定义为值类型时,Go 语言编译器会自动做转换,所以值类型接收者和指针类型接收者是等价的,编译不会报错,运行也都可以调用相应方法。package mainimport "fmt"type A interface { echo()}type B struct { b string}func ...

2020-11-30 22:09:51 834

原创 手把手教你用dlv和gdb调试GoLang

无论哪种方式,都要配置gdb钥匙串,参考这篇文章:https://blog.csdn.net/qq_33154343/article/details/104784641package mainimport ( "fmt")func a(){ fmt.Println(111);}func main() { a() s := []int{1, 2} s = append(s, 3, 4, 5) fmt.Println(len(s), cap(s))}dlvsi要进入r

2020-11-27 23:09:12 1983

原创 Redis源码之——跳表skiplist原理和源码调试

码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071原理Redis的zset是一个复合结构,有以下几个特性:hash存储value-score的对应关系 按照score排序 指定score范围获取value列表 获得某个元素的排名当zset的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认为64字节)使,redis会用ziplist存储zse.

2020-11-26 22:12:43 464

原创 Redis调试关键断点和多路复用流程

server.c ->void initServer ae.c ->int aeCreateFileEvent networking.c ->void acceptTcpHandler networking.c ->static void acceptCommonHandler networking.c ->client *createClient ae.c ->int aeCreateFileEvent networking.c -> vo...

2020-11-25 17:13:46 329

原创 高并发场景利器之限流

WHY,为什么需要限流? 举一个常见场景,鄙人居住在北京,大天朝的地铁早高峰远近闻名,地铁人满为患,此时我们的安检员大大们会拉起长长的隔离线,乘客们有序排队进站。为什么要这样做呢,让大家自己随意进入会有什么问题呢?因为通过工作人员慢慢引流,会有效减少站台的压力,不会使大量无秩序乘客蜂拥而至堵在站台,导致想上的人上不去,想下的人下不来,地铁车门关不上,影响地铁正常行驶,还会引发冲突甚至安全事故。所以限流是为了保证每一位乘客最终能够顺利上车,同时保持整个过程井然有序。 回到我们...

2020-11-24 17:22:08 753 2

原创 搞懂这些,让MySQL性能监控和优化事半功倍

有多少人关注过自己MySQL性能?你现在的MySQL已经优化到极致了么?如何发现自己的MySQL性能问题?DROP TABLE IF EXISTS `hq_price`;CREATE TABLE `hq_price` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增属性', `province_id` int(10) unsigned NOT NULL COMMENT '省id', `city_id` i.

2020-11-18 12:54:51 1170

原创 MySQL是如何实现事务ACID四个特性的?

事务的实现要了解事务是如何实现的,必须要先了解4个概念:redolog undolog purge group commit下面将分别介绍。redolog重做日志用来实现事务的原子性和持久性,主要需要关注下面几个概念点:日志由两部分组成,一部分是内存中的重做日志缓冲(redo log buffer),是容易丢失的,另一个部分是重做日志文件(redo log file),是持久到磁盘的。 为了确保每次日志都写入重做日志文件,在每次将重做日志缓冲写入重做日志文件后,InnoDB引擎

2020-10-30 21:51:41 1501

原创 PHP实现opentracing链路追踪

说点废话之前写过一个GoLang版本的opentracing客户端实现,由于部门大部分服务还是用PHP实现的,所以打算用PHP实现一个基于jaeger的客户端。GoLang版本:https://success.blog.csdn.net/article/details/104100597参考文档和开源组件opentracing文档:https://wu-sheng.gitbooks.io/opentracing-io/content/pages/spec.htmlopentraci.

2020-10-24 23:51:00 2423

原创 MySQL编译安装和lldb源码调试

安装MySQL1、下载linux通用源码:wgethttps://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.18.tar.gz2、解压压缩包:tar -zxvf mysql-8.0.18.tar.gz3、安装依赖工具:yum install cmake gcc-c++ ncurses-devel perl-Data-Dumper boost boost-doc boost-devel git4、删除CMakeCache.txt5、.

2020-10-10 01:24:32 859

原创 MySQL主从复制原理、实践和常见问题

配置主从注意:需要初始化启动2个mysql实例,需独立2个mysql实例目录和配置文件,安装参考:https://success.blog.csdn.net/article/details/83660180master配置文件:[mysqld]port=3306basedir=/usr/local/mysqldatadir=/usr/local/mysql/datacharacter-set-server=utf8lower-case-table-names=2default_

2020-10-04 17:31:15 928 2

原创 关于MySQL索引和filesort原因的探究

为何要探究之前对 MySQL 的索引和文件排序有过一些了解,但是只是大概知道查询条件满足最左原则用到索引列,排序字段在用到的索引列中,就可以避免文件排序。很明显自己了解不到位,因为关于where字段和order by字段,会有很多种不同的组合场景,今天做几个实验探究下。探究过程表结构CREATE TABLE `t_price` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `customer_id` bi

2020-09-18 22:16:00 854

原创 一篇文章玩转GDB/LLDB调试Redis源码

一、安装调试版redis参考博客:https://success.blog.csdn.net/article/details/83659776注意需要在makefile的开头定义CFLAGS 变量:CFLAGS = -g ,否则调试过程中无法跟踪代码二、使用gdb启动redis-serversudo gdb /usr/local/bin/redis-server会遇到如下问题:(gdb) r Starting program: /usr/local/bin/redis-ser

2020-08-09 21:39:48 708

原创 关于GoLang的concurrent map writes错误

作为一个GoLang萌新(其实就是并发编程萌新,之前一直在做PHP),对并发下共享资源的竞争了解不多。所以一开始写出了如下代码:type OriginPriceController struct { OriginPriceService *origin_price_service.OriginPriceService}func (self *OriginPriceController) action() { var wg sync.WaitGroup wg.Add(2) go f

2020-08-01 20:17:34 9445 3

转载 【转载】GoLang逃逸分析

写过C/C++的同学都知道,调用著名的malloc和new函数可以在堆上分配一块内存,这块内存的使用和销毁的责任都在程序员。一不小心,就会发生内存泄露,搞得胆战心惊。切换到Golang后,基本不会担心内存泄露了。虽然也有new函数,但是使用new函数得到的内存不一定就在堆上。堆和栈的区别对程序员“模糊化”了,当然这一切都是Go编译器在背后帮我们完成的。一个变量是在堆上分配,还是在栈上分配,是经过编译器的逃逸分析之后得出的结论。这篇文章,就将带领大家一起去探索逃逸分析——变量到底去哪儿,堆还是栈?

2020-07-28 17:51:47 285

转载 设计模式六大原则【文章来源:新亮笔记-编程是一种思想,而不是敲代码】

编程是一个先思考再编码的过程,思考是优于编码技能的,在思考过程中我们会考虑代码的可重用性、可靠性、更容易被他人理解,这时就会使用到设计模式让代码编写工程化,这篇文章整理了设计模式的六大原则。单一职责原则单一职责原则(Single Responsibility Principle)There should never be more than one reason for a class to change.(有且仅有一个原因可以引起类的变更)不管让我干啥,我都只干一件事,

2020-07-24 13:04:19 391 1

空空如也

空空如也

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

TA关注的人

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