- 博客(43)
- 收藏
- 关注
原创 用golang实现一个熔断器
首先贴出仓库地址:https://github.com/JeffreyDing11223/goBreaker这个熔断器实现简单,使用方便,同时大家也可以fork后进行自己需要的改造,当然,也欢迎大家提pr,一起优化goBreaker下面介绍下goBreaker:goBreaker状态机状态转换逻辑初始为closed状态,一旦遇到请求失败时,会触发熔断检测(见下方的 ShouldTri...
2019-01-01 15:38:14
2641
原创 mysql分库分表技术选型时需要注意的点
首先需要明确的一些概念和问题:原先:一个库一张表,即db和table。水平拆分之后:多个库多张表,即 { db1,db2,db3,… } 和 { table1,table2,table3,… },假设现在有物理机器 { server1,server2,server3,… },那么这三者之间的对应分配关系是?是一对多还是一对一?在中间件看来,shard指的是db这个维度?中间件目前对sq...
2018-12-16 20:57:28
644
原创 Quic协议介绍和浅析
Quic协议介绍和浅析一,Quic全称是什么?QUIC 全称 Quick UDP Internet Connection, 是Google制定的一种基于 UDP 协议的低时延互联网应用层协议。二,Quic的优势和应用场景1,为什么需要Quic:近三十年来,tcp协议发展得非常缓慢很多网络中间层,比如防火墙、网关等,都强依赖于tcp指定的各类规则,所以tcp的修改很容易由于这些中间环节...
2018-11-24 16:01:46
8787
原创 结合innodb的B+树索引来优化sql查询一例
先上表结构:CREATE TABLE `quote_xxxxx` ( `instrument_id` varchar(20) NOT NULL, `time_type` varchar(20) NOT NULL, `datetime` datetime NOT NULL,... `metal` varchar(20) NOT NULL DEFAULT '', PRIMARY...
2018-09-30 10:30:41
509
原创 制作docker镜像构建gcc+boost的容器
基础镜像选用alpine DockerFile如下 :FROM alpine:latestLABEL maintainer="me"LABEL description="An environment with Boost C++ Libraries based on Alpine Linux."ARG BOOST_VERSION=1.67.0ARG BOOST_DIR=boost_...
2018-08-24 20:25:58
2221
原创 用go实现的kafka客户端,基于sarama和sarama-cluster
工作中需要将原先的消息队列替换成kafka,于是接触了基于go实现的sarama,又因为sarama不支持consumer group,于是又使用了sarama cluster,同时因为需要尽量保证消费一次的语义,就自己造了个简单的轮子,把sarama和sarama cluster封装到一起,同时实现了保证消费一次的语义,我给它起名为kago。先附上kago的依赖,需要先进行安装:go...
2018-08-05 22:51:08
23698
1
原创 golang httpServer对于keepAlive长连接的处理方式
当下http1.1对于长连接是默认开启的,golang的内置httpServer也很好的支持了这一点。今天查阅资料时,发现自己写了这么多的接口,但是对于httpServer是如何实现长连接的,却一时说不上来。于是就去go的src源码里面翻了翻。本文只讨论server端是如何确保长连接的,client端如何确保呢,这里先简要说一下,当调用client.Do()函数后,通过transport去获取...
2018-07-26 16:35:19
10350
原创 grpc基于golang的客户端服务端整体预览
proto文件:/** @Title: 服务接口说明* @Description: 接口目录*/service SpotDataHandler { rpc GetProductInfo(GetProductInfoRequest) returns (GetProductInfoResponse) {}//获取所有商品信息}/*** @Title: 统一说明* @D...
2018-07-06 20:52:31
927
原创 kafka消息交付语义的分析
在kafka中,在producer和consumer这两个维度上都有三种消息交付的语义:At most once ---- 消息可能会丢失但绝不重传.At least once ---- 消息可以重传但绝不丢失.Exactly once ---- 每一条消息只被传递一次.先来看producerproducer设置中有这么一个选项:每发送一次消息,都会要求broker返回...
2018-06-22 19:59:51
1816
原创 golang结合Kafka消息队列实践(二)
上周分享了如何使用go来对kafka进行生产和消费,这周接着对kafka消息队列的一些特性来进行使用。 上次讲到kafka有个consumer group的概念,而我们使用的sarama并没有支持,所以这次引入sarama-cluster项目 : go get “github.com/bsm/sarama-cluster”producer的代码不变,参考上一篇文章,consumer的代码改为...
2018-06-15 18:42:16
6834
原创 golang结合Kafka消息队列实践(一)
公司决定使用kafka来作为新一代的消息队列来使用,于是开始对kafka的机制,原理,go客户端的使用,各种了解了一番,过程中也遇到了不少的坑,特地写出来,和大家分享,也供自己参考,加深印象。首先,kafka的设计思想,各个角色比如broker,producer,consumer,partition等等还有与它们相关的配置,这里就先不作介绍了,官方文档都有,文章后面也会提到。附上kafka...
2018-06-07 20:49:28
24480
5
原创 golang处理http response碰到的问题和需要注意的点
在处理http response的时候,偶然发现,body读取之后想再次读取的时候,发现读不到任何东西。见下方代码:
2018-05-25 20:50:22
18704
原创 mongodb中upsert和insert的使用注意
新服务已经上线跑了差不多两周,暴露出一个问题,我们发现db进行upsert的速度越来越慢,以前两个小时就能消费完队列里的数据,现在需要四五个小时,并且消耗时间是呈现不断上升的趋势。所以我觉得应该是和upsert这个操作有关。问题定位: 1,由于是写多读少的场景,所以我们并没有对集合加入索引。并且经查阅资料发现,mongodb索引的存储机制和mysql不同,mysql的索引是存储在硬盘中,需要...
2018-05-18 16:31:51
40204
1
原创 发现mgo的一个坑,以及解决过程
碰到的问题: 在使用”https://github.com/go-mgo/mgo“过程中发现,当大量多次交互之后,也就是服务运行大概一到两个小时之后,会出现cpu占用率极速上升的情况,并且是必现的。所以我用pprof的火焰图来分析了一下,到底是哪里占用了cpu: 从火焰图能很明显的看出来,是 SaltPassword() 占用了大部分资源,即 func (s *Session) ...
2018-05-04 19:50:35
2364
原创 golang服务与mongodb交互,以及驱动mgo源码浅析
公司大数据部门有一个需求,要将所有的交易数据进行落地,以便进行分析和价格预测等等。具体场景: 1,写多读少 2,数据量庞大,并且每天日益增长为什么选mongodb: 1,mongodb是弱数据结构模式,每个文档之间的结构互不影响,日后如果需要增加字段直接增加即可,对集合不会产生任何影响。 2,分布式,面对庞大的数据量,mongo原生支持sharding存储。 3,无事务和join...
2018-04-29 17:41:47
1790
1
原创 redis主从加哨兵模式的实践
redis是一个基于内存的kv数据库,其吞吐性能可想而知,随着redis应用得越来越广泛,以及对它的依赖程度越来越高,它的高可用便成了需要考虑的一个很重要的点。于是今天在自己电脑上实践了一下redis的主从模式和哨兵监控。基本架构:一主二从,加一哨兵先为master和slave编辑配置文件: 为它们配置ip和端口,这里6379是master,6380和6381为slave...
2018-04-22 23:18:36
1331
原创 golang sync.once的应用
sync.once是被用于全局执行单次函数的场景,用法比较简单。 我们用到它主要是为了单元测试的执行,因为有些单元测试的函数需要和db交互,还有log的初始化,config配置文件的初始化,等等,这些其实都只需要执行一次就够了,对于单元测试来说,如何知道这些是否执行过呢,那就用sync.once,这样我就不需要关心这些是否重复执行,只要在每个用例的最前面执行sync.once的方法就行了。s...
2018-04-13 18:43:34
1576
原创 基于gin的单元测试之httptest
目前我们的后端服务提供大量的restful api接口,每次上线都需要测试那边回归一遍这些接口,造成人力的浪费。正好借着这次单元测试和持续集成,我们引入了httptest框架,结合gin来做接口单元测试。httptest是golang官方提供的一个包,位于/src/net/http/httptest下。其原理的话我也看了源码研究了下,这里大致说下,它有一个ResponseRecorder结...
2018-04-04 16:53:04
9032
2
原创 golang单元测试之mock
搞单元测试,如果碰到这些情况: 1,一个函数,内部包含了很多并且很深的调用,但是如果单单测这个函数,其实实现的功能很简单。 2,一个函数,包含了其他还未实现的调用。 3,函数内部对数据的要求极为苛刻。那么这时候就可以考虑使用mock来处理。mock,简而言之就是可以通过注入我们所期望返回的数据,或者我们所期望传递的参数,来避免上面那些情况,其原理则是通过反射来实现。这次就来看看g...
2018-03-30 21:01:58
7947
原创 走进golang单元测试
工作需求,各个服务的代码需要陆陆续续加入单元测试。作为这次单元测试和持续集成持续发布的推动人,这几天都在查找golang单元测试相关的资料和实践。单元测试的作用: 提高代码的可维护性。 代码的可维护性是指增加一个新功能,或改变现有功能的成本,成本越低,可维护性即越高。 是修改代码乃至未来代码重构的信心保证。 持续集成的重要部分。单元测试需要注意的点: 单元测试的测试用例要覆盖常用...
2018-03-23 20:12:35
645
原创 使用Go1.9的sync.map
在Go1.9之前,go自带的map不是并发安全的,也就是说,我们需要自己再封装一层,给map加上把读写锁,比如像下面这样:type MapWithLock struct { sync.RWMutex M map[string]Kline}用MapWithLock的读写锁去控制map的并发安全。 但是到了Go1.9发布,它有了一个新的特性,那就是sync.map,它是...
2018-03-16 21:15:13
4538
翻译 用golang来面向对象编程
我们都知道,面向对象的三个要素:封装,继承,多态。而golang其实不能称之为严格意义上面向对象的语言,但我今天在网上翻阅到一篇用golang来写面向对象代码的文章,提供了一个思路,是英文的,这里我把它翻译了一下,供大家和自己参考。先送上传送门:http://yourbasic.org/golang/inheritance-object-oriented/翻译:传统的面向对象编程中提供...
2018-03-07 20:26:14
1017
原创 http跨域问题处理之CORS
如何算跨域首先,跨域属于浏览器的行为,服务与服务之间不会产生跨域问题。当一个请求url的协议、域名、端口三者之间任意一个与当前页面的不同即为跨域。在CORS之前的解决方法是在同域内做一个代理,或者使用JSON-P等。随着跨域请求的应用越来越多,W3C提供了跨域请求的标准方案--- CORS模型(Cross-Origin Resource Sharing)。目前主流浏览器均支持CORS。...
2018-02-23 21:07:08
382
原创 用Go来爬虫 goquery使用
应工作内容需求,要爬取两个网站的数据(至于是什么网站,这里就不透露了,哈哈,害怕被发现了封ip),这些数据是定期更新的。由于后端的所有服务都是用go写的,于是不打算用python,还是想用go来完成这个需求,github里搜了下,发现goquery这个爬虫包用的人还挺多的,5000多个star,而且是BSD开源协议,于是毫不犹豫的拿来用了。首先,go get https://github.co...
2018-02-12 21:06:09
13057
4
原创 golang 字符串编码转换 gbk转utf8
问题描述: 需要调取一个第三方的接口,接口返回的内容的编码格式是gbk的,但是golang内建只认utf8,所以需要将gbk的字符串转换为utf8,才能进行后续的数据处理。问题处理: 引入开源包 go get github.com/axgle/mahonia 此包的开源协议是BSD,所以可以放心的引用和使用mahonia源码解读:// ConvertString converts...
2018-02-08 11:21:03
17866
原创 golang读写锁使用
今天调试程序发现一个报错:fatal error: concurrent map writes 是因为多个goroutine对同一个map产出了竞争,解决这个问题的方法有两个,一个是用sync.Map,另一个是加锁。sync.map是go1.9新加的特性,这里暂且先不讨论。而且当前业务场景用读写锁完全可以解决,所以决定使用读写锁。先温习一遍概念:1、互斥锁 其中
2018-02-02 20:55:53
8487
原创 分享一个redis很简单却又很极致的操作(INCRBY指令)
今天无意中搜到了一个redis的操作,算是把redis指令发挥到了极致了。要解决的问题:用户签到,一天只能签到一次。由于redis开启了主从模式,写走主库,读走从库,如果用普通的set和get指令,万一面对高并发情况,刚刚在主库set完,还没到同步到从库的时候,去从库get,得到的还是未签到的状态,导致可能会重复签到多次。然后骚操作开始:利用 INCRBY key increment
2018-01-26 21:06:49
6977
1
原创 golang中的三个点 '...' 的用法
‘…’ 其实是go的一种语法糖。 它的第一个用法主要是用于函数有多个不定参数的情况,可以接受多个不确定数量的参数。 第二个用法是slice可以被打散进行传递。下面直接上例子:func test1(args ...string) { //可以接受任意个string参数 for _, v:= range args{ fmt.Println(v) }}
2018-01-25 21:10:22
66792
15
原创 mysql中 执行计划的extra字段---- using where , using index 和 using where & using index 整理
先上表结构: CREATE TABLE table ( xxx varchar(20) NOT NULL, yyy varchar(20) NOT NULL, zzz datetime NOT NULL, aaa varchar(10) NOT NULL, PRIMARY KEY (xxx,yyy,zzz), ) ENGINE=InnoDB DEFAULT CHARSET=utf8m
2018-01-19 11:43:23
25172
14
原创 mysql explain执行计划 参数解读
explain使用 随着业务逻辑的复杂化和数据量的扩展,慢sql的问题就会出现,此时需要通过查看执行计划来对一些慢sql进行优化,下文是对explain的各个参数的解读。参数解读 在sql语句前面加上explain关键字,即可查看执行计划。如: explain select instrument_id from quote_kline_1day where instrument_
2018-01-14 22:21:27
533
原创 mysql 聚集索引 非聚集索引 概念梳理
聚集索引 一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。 聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(联合索引)(不过mysql的innodb只支持主键聚集索引,不支持联合聚集索引),就像电话簿按姓氏和名字进行组织一样。非聚集索引 一
2018-01-07 21:44:24
8329
4
转载 redis 用scan指令 代替keys指令
本文转自:http://blog.csdn.net/qq_27623337/article/details/53201202众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会阻塞服务器,对单线程的redis来说,简直是灾难,终于找到了替代命令scan。SCAN cursor [MATCH pattern] [COUNT count] SCAN 命令及其相关的 SSCAN
2017-12-28 15:01:44
994
原创 golang程序的监控神器----expvar
大家都知道,go自带的runtime包拥有各种功能,包括goroutine数量,设置逻辑线程数量,当前go版本,当前系统类型等等。前两天发现了go标准库还有一个更好用的可以监控服务运行各项指标和状态的包—-expvar。 expvar包为监控变量提供了一个标准化的接口,它以 JSON 格式通过 /debug/vars 接口以 HTTP 的方式公开这些监控变量以及我自定义的变量。通过它,再加上met
2017-12-24 20:11:47
15970
8
原创 程序代码里不要使用select * 的两个理由
1,不需要的字段会增加数据传输的时间,即使mysql服务器和客户端是在同一台机器上,使用的协议还是tcp,通信也需要额外的时间。 2,select * 可能会获取到自己不需要的列,如果以后表结构修改了,同样也可能会对代码产生影响。比如表增加了一个字段,而我代码与其对接的对象属性里没有这个字段,select * 就会导致报错。
2017-12-23 21:53:47
2960
1
原创 redis缓存策略小结
比较常用的缓存策略,同样这也是facebook的缓存策略: 1. 读:应用程序从cache中取数据,取到后返回。 2. 读:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。 3. 增删改:先把数据存到数据库中,成功后,再让缓存失效。 这里针对第3点,会有一些其他的用法,乍一看都是很正常的,但后来细细一想其实都是有问题的。 比如(1)“先更新redis,然后更
2017-12-16 23:51:06
11118
3
原创 redis命令快速检索
Key(键) DEL 删除给定的一个或多个key,DEL name ,DEL name type website DUMP DUMP KEY,序列化给定 key ,并返回被序列化的值,使用 RESTORE 命令可以将这个值反序列化为 Redis 键 EXISTS 检查给定 key 是否存在。若 key 存在,返回 1 ,否则返回 0 。redis> EXISTS
2017-12-10 20:54:55
2300
原创 redis性能调优一则
redis作为提升web服务端数据交互能力的重要利器,其本身也有开销,为了让redis变得更快,有必要对和redis交互的地方进行性能优化。 今天说一下golang中比较著名的一个redis库—-redigo。它的conn.Do()、Send()、Flush()、Receive()的合理使用是很有必要的。 先上一个我本地测试的例子:func main(){ _=InitRedis(10,"
2017-11-26 01:18:16
980
原创 闭包,使用不当,会出问题
同事在初始化redis配置的时候,给Dial函数赋值时用了闭包,导致程序上线后,数据怎么都加载不到redis中去,排查了半个多小时,总算找到了罪魁祸首。虽然自己之前对闭包也算了解,但是看到他的那段代码的时候,乍一看竟也没发现出问题来,所以决定写篇文章加深印象,避免自己以后也犯类似的问题。 先上代码:func InitRedis() error { GRedis = make
2017-11-18 22:16:13
488
原创 写golang restful接口时遇到的一个坑
话不多说,先上代码type detail struct { High float64 `json:"high"` Low float64 `json:"low"` Average float64 `json:"average"`}type Spot struct { UpdateDate string `json:"update_date"` Detai
2017-11-12 17:05:19
900
原创 golang中map和slice的查询速度比较,结果意想不到
看到标题,第一反应,map肯定秒杀slice啊,我当时也是这么想的,毕竟前者的查询复杂度是O(1),后者是O(n)。 但是,事事难预料哦,用代码来说明问题:先写两个测试函数var testTimeSlice=[]string{"aa","bb","cc","dd","ee","aa","zz"}var testTimeMap = map[string]bool{"aa": true, "bb":
2017-11-05 18:09:25
14112
4
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人