自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(79)
  • 收藏
  • 关注

原创 元数据管理的必要性

工作中的一点体会通常业务初期,为了快速实现需求,对某一业务实体,会疯狂新加字段。常见的方式是搞一个大map,什么都往里面塞。短期内收益确实比较明显开发快,能够迅速解决新需求和业务实体的绑定关系,可以快速引入新feature维护成本低,只需要维护一个服务的稳定性即可但是长远看是个潜在的雷点并发问题写覆盖,多个写入方难以保证原子性相互覆盖,如果牵扯到跨机房同步,冲突解决很困难数据模型不清晰,后期瘦身极其困难数据的定义不清晰,废弃字段过大但又无法清理,删除又容易引入问题业

2020-10-27 21:37:06 705

原创 go map并发panic问题

最近工程上有段代码panic了,发现又是犯了map并发写的问题。自己来回顾一下这个问题,避免自己也犯错go map写入的源码在这里其中有一段throw exception和写入标志位的逻辑 if h.flags&hashWriting != 0 { throw("concurrent map writes") } hash := t.hasher(key, uintptr(h.hash0)) // Set hashWriting after calling t.hasher, sin

2020-08-29 21:16:22 2314 1

原创 跨机房环境下常见的唯一键处理方式

当业务发展到一定程度,出现了跨机房的时候,我们往往会面临历史原因中一些唯一键的处理,有些是自增键,有些是C端设置的,本问探讨下怎么解决这个问题数字键常见于db的自增主键或用户生成时的随机id对于自增主键这种毫无业务含义的字段,通常采用id生成器进行替换,一般团队都会有通用的id生成器,方法一般也是基于比较主流的id生成算法,可以参考id生成器对于用户生成时的随机id,一般就具有了一些业务id,比如该id可以用于应用中的搜索添加好友等(比如QQ号),这种情况下,id生成器这种会生成长id的工具就不能满

2020-08-15 14:57:46 332

原创 代码行数统计

最近做一些批量化的改造,需要预估团队整体工作量。因为按业务本身复杂度来统计需要熟悉所有代码,执行上很难操作,因此用代码行数来评估工作量研究了几种工具和方法python的line包直接安装pip install line-counter,以goredis目录为例子wjcdeMacBook-Pro-2:redis wujingci$ lineSearch in /Users/wujingci/go/src/github.com/go-redis/redis/file count: 68line

2020-08-09 01:53:24 654

原创 go mod在工程中的使用原则

gomod是go的包管理工具,可以方便地管理依赖。减少git目录本身的容量,是一个很好的工具,但是在工程事件中出现一些疑惑,gomod到底该不该出现在通用包中呢。下面是几点思考支持通用包需要依赖的通用包是对外提供能力的,因此需要确保逻辑本身是可用的。在通用包中定义的方法在特定的依赖版本上是经过测试可以正确正常执行的例如:假设通用包是B,依赖通用包的是应用包C。B和C依赖了不同版本的A包B依赖了1.0的A包方法a,C依赖了2.0的A包中的方法b。b是新方法,必须使用2.0的A包,但是2.0的A包更新

2020-08-05 02:11:30 203

原创 常见qps限制方式

生产环境经常会跑一些离线任务,或者有一些异步任务在问题恢复后积压需要放水,此时我们需要控制对下游的访问qps,避免打挂下游,有多种方式去实现。当你是一个单进程/单携程通常是一些小的回扫任务,多用于处理临时任务。因为是单个进程/携程,简单的话可以首先time.Sleep()较长一段时间,同时打一下执行时间的大概日志,然后根据实际调用下游的时间,估出一个值调整下游的qps。如果下游超时不稳定有尾...

2019-09-07 21:21:57 10336

原创 业务实现中的本地缓存(GO)

实际业务实现中常常会使用到本地缓存,用以减少对实际存储的访问,我们会针对不同的使用场景设计不同的缓存模式,但是基本的实现方式都是一个巨大的Map/Table(不同语言)。下面用go来说,总体的实现都是通过一个,根据不同的需求,LFU,LRU再设计map里面具体的entry的struct,保存需要的计数用来做淘汰,下面从不同使用角度来说明一下普通的保存配置项的本地缓存实际使用中,某些中台服务/服...

2019-09-01 17:29:34 2925 1

原创 google和facebook token验证模式

实际开发海外版应用的时候,我们常常有使用google和fb的token和id来验证身份的情况,甚至或者一些功能公开的graph信息,本文主要交代怎么用token和id来验证Google实效性:1h左右google是portal token,时效较短google api官方文档:https://developers.google.com/+/web/api/rest/latest/peopl...

2019-06-16 00:55:47 3728 5

原创 golang中的json decode丢失精度的问题

最近发现的一个坑当用enconding/json包的时候,数字默认是处理为float64类型的,这就导致了int64可能会丢失精度,这时候要用dec.UseNumber将处理的数字转换成json.Number的形式,再自己去做type assertion代码package mainimport ( "fmt" "encoding/json" "strings")func Cr...

2019-02-04 17:34:44 2956

原创 用嵌套的两个kafka实现突发性高并发consumer

今天遇到一个问题,某个kafka comsumer特别耗时,排查发现,之前把一些操作写成串行了,但是这个comsumer属于那种来一波消息就中断的,改成并行的又需要大量资源(CPU/MEM),不划算。后来同事提供了一种思路,将并行的操作拆另一个comsumer里用一个进程分个处理,这样前一个comsumer可以及时消费掉,并且不耗费资源,后一个comsumer串行地处理就不会有很长的耗时,解决了...

2018-09-29 01:34:47 566

原创 用go-wrk,go-torch做服务器压测和性能分析

常常会有这样的场景,写了一个接口,上线发现性能不大好,费资源处理慢,可能是某个rpc耗时长,可能是可以并发的地方没有做并发,但发现问题比较麻烦,最好能有一些可视化的工具。当然我们能这么做,是因为go语言集成了profile采样工具,并且允许我们在程序的运行时使用。准备工作写个最简单的web server,一个helloworldpackage mainimport ( ...

2018-09-09 21:37:40 2869 1

原创 分布式id生成器

id生成器在工作中比较常用,是为了有一个全局唯一性的值。最早接触的是uuid,因为使用方便,java1.5以后的util包里就有声称uuid的函数 UUID由当前时间(纳秒级),机器的ieee识别码(网卡mac)和随机树来生成,重复几率极低,现有的工程数据级别根本不用考虑重复,当然我不知道基因工程里面对细胞等的解析会不会超过这个数量级。 缺点是太长了,online id生成器上生成一个感受...

2018-07-15 17:46:12 339

原创 数据库表的自增键设计

最近做了一些涉及到分库分表和跨机房drc的业务改造,包括了一些导数据的工作,为了数据连续性,我觉得一个自增的值还是需要的,简单靠id生成器当表大小达到一定程度会变得难以扫表。1.项目初期,为了快速开发,往往会使用一个自增主键。优点在于表存储性能会好,而且便于扫表统计数据,因为有一个连续的字段。 2.随着项目扩大,分库分表形成了一个趋势,这时候就要摘掉自增主键,或者用别的方式存储这个自增主键,...

2018-07-15 16:42:20 819

原创 热门缓存的实现方式

做社交过程中,常常会有一些热门的用户,内容等等。我了解到的基本有两种实现方式,里面也有些细分 1. 给热门用户内容专门建一个redis, a.每次出现热门用户,内容,可以由运营操作给通过在运营平台给用户或内容加热,加到redis里面。 b.在现有的计数缓存里加额外的计数,对于获赞数或者评论数频率做个统计,每隔两分钟清一下,两分钟内超过100赞就自动mark成热门内容加入red...

2018-06-18 23:08:07 373

原创 python lower方法的局限性

日常工作中,往往有很多大写转小写的需求。 比如设计es索引的时候往往会把大小写相同的分词归在一个索引内,这样请求输入也会强制转成小写再去查询。 python2.7因为其对unicode的不友好,导致lower()这个方法有一定的局限性,尤其是处理特殊unicode字符的时候。看下面的例子>>> "AEIOU".lower()'aeiou'>>> "Æ...

2018-06-18 19:40:49 1686

原创 golang sort包

golang sort包可以对所有实现了sort.interface的接口对象slice排序,排序时候使用的是插入排序,快速排序还是桶排序是包自身选择的,当你做的排序并没有极高的性能要求时,可以直接使用sort包里的方法。 这是官网定义的例子type Person struct { Name string Age int}type ByAge []Personfun...

2018-06-18 16:20:36 748

原创 项目中错误类型的定义和思考

现在开发业务都是微服务,api调用rpc,rpc之间互相调用。除了常规的链接失败或超时以外,还有很多业务上的错误。为了使返回的错误码容易判断和查错,通常会靠一个统一定义的错误代码映射表。其实我们平时http的各种错误码也就是一个映射表。 有一种做法是代码里写死一个映射表文件,每次有新增去修改这个文件。但是当系统渐渐变大。业务可能会按模块进行拆分并接耦合,业务之间可能只是一个对接,代码repo...

2018-05-26 21:55:09 774

原创 Mysql死锁问题

最近遇到一个mysql抖动的问题,看写库的load和io其实都不高,但是会有突然的活跃链接的激增,查下来是发生了循环的死锁,以前不太了解这块知识,稍微看了一下,在这边总结下。INNODB通过MVCC实现了事务 在并发的环境中会有如下问题 1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。 2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次...

2018-05-19 17:04:36 415 1

原创 python yield from用法

yield from是python3.3之后新增的用法,主要是作为caller和genertor之间的通道来使用的。先说从generator读,比如接受从yield出来的结构def generator(): for i in xrange(10): yield ifor i in (yield from (generator())) print i还...

2018-05-01 18:23:28 1744

原创 tornado实现python异步

这是facebook开发的一个异步调用库。gevent是future的模式,而tornado则是callback的那种形式。在其他语言比如java中,future本身就是一个实现好的接口,取值只需要调用get()获取返回然后再用框架比如Spring等等实现注入即可,而callback则预先需要定义好返回的结构体。在python中没有这个问题,因为是动态语言,返回的结果是可以即时的使用和处理的。 ...

2018-05-01 16:52:34 1183

原创 python用gevent实现异步

实际工作中,往往会使用碰到文件io或者网络io。 批处理大量文件或者做爬虫,如果使用同步的方式,大量时间都会消耗在io的等待上,尤其是网络IO,包括建立socket,下载,这个很大程度上取决于网络环境,比如我们去网上爬取一些图片做一些图像处理的训练啊等等。爬取后执行的动作耗时其实很短,90%的时间都耗在网络IO上了,我们就要考虑异步了。 比如我们爬取人人网,微博等平台的资料,因为大家的首页都是...

2018-05-01 13:45:38 4646 1

原创 awk进阶

以前用awk通常就是grep之后打出某一段的日志再sort | uniq一下统计出错类型,最多再加个-c统计下个数。那天看一同事用的极6,所以查查资料学习学习。先说说我会的 1. 查看不同的UID并统计个数 以ps -ef 为例 ps -ef | awk '{print $1}' | sort | uniq -c 当然也是支持printf那种格式化输出的,写法和C语言一样过滤出/...

2018-04-20 09:32:35 205 1

原创 msgp的用法和一些局限性

msgp是golang用来做序列化的一个工具获取方式: go get github.com/tinylib/msgp以官网例子来看wujingcideMacBook-Pro:msgp wujingci$ cat my_types.gopackage maintype Person struct { Name string `msg:"name"` ...

2018-04-15 20:46:13 2322 1

原创 goland合并branch技巧

可以用goland,pycharm,intellij等idea方便地去合并代码。这里用goland举个例子,pycharm和intellij是更成熟地ide,功能只会更加强大。 随便找个项目,以go-redis为例子好了。我建两个分支,test和test2 然后分别在两个分支上做些改动。这里仅仅为了举例,改动毫无意义。 这样,test改动command相关的文件,test和test2同时...

2018-04-07 19:46:31 8321

原创 golang微服务的设计架构

最近看了现在公司的golang代码架构,再结合golang的语言特性和现有包管理的局限性,觉得有些不合理。想在接下去技术改造过程中调整一下。写出来,如果大家有什么好的意见和建议希望和我探讨一下。首先,既然是微服务,应该是尽量解耦合的。可以允许有工具类,但是不可以有一个巨大的common包,里面不能带有对其他微服务依赖的逻辑,不然这个包一更新会给所有微服务造成测试压力。对于工具类,与其集中在一...

2018-04-06 17:28:30 5295

原创 redis容量估算

工作中常会用到redis做存储型的kv存储,如何合理地估算所占空间呢?首先要看看redis的存储原理,redis存储时候kv都会被处理成字符串或者说字符数组,redis实现了一种方便进行append,rehash等操作的sds类型。 在sds.h可以看到typedef char *sds;这样的定义。光这样和普通的字符串看上去毫无区别,事实上sds有一个header的概念,同样在sds.h里...

2018-04-01 20:31:15 6832

原创 python的计算符优先级

python为了风格更简洁,和其他语言相比有一些特殊的运算符,这里面容易踩到坑。本周遇到一个,所以整理一下这方面。逻辑运算符优先级not>and>or 这次犯的错误就是判断条件 按照从左到有的顺序很明显是False,但其实python是先算and的。>>> True or False and FalseTrue算数运算符** 表示幂运算...

2018-03-31 11:52:44 583

原创 golang time包做时间转换

Time类型 Now方法表示现在时间。 func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time 返回现在的时间,func (t Time) Unix() int64将时间转换为unix时间戳,因为duration的限制,所以应该只能计算从1970年开始的250年左右 func...

2018-03-26 00:05:14 8538

原创 代码设计的注意点

总结一下最近工作中体会到和学到的点虽然要求快速迭代,比如说python开发下,还是要注意代码的扩展性,不能为了快速上线牺牲掉代码扩展性,能封装的尽量封装成类,然后再把他当基类去扩展,短期内不明显,但长期以来肯定是有好处的,比如dao层,通常只会使用一种orm框架,所以支持的增删改查模式都是一样的,就可以自己扩展,做一些get_or_create,update_if_exist之类的封装,这样...

2018-03-25 11:52:41 590

原创 pyhon迭代器和yield

python yield其实是迭代器的一种简单写法一般的迭代器会定义__iter__函数 比如以斐波那契数列为例>>> class Fabo(object):...... def __init__(self, max):... self.max = max... self.n, self.a, self.b = 0, 0, ...

2018-03-24 09:46:35 298

原创 pdb调试python代码

本来只知道可以用pycharm,eclipse这类东西打断点。今天同事告诉我才知道原来python本身也有工具pdb,这个名字应该来自c语言的gdb吧=。=使用很简单,import pdb即可,在需要开始断点的地方加上 pdb.set_trace()即可。调试中命令b 打断点,常用于循环,这样下次循环可以在此处停住 c 继续执行直到下一个断点 l ...

2018-03-20 00:46:22 313

原创 golang strings包整理

所有语言都有字符串处理的包,今天整理下golang的strings包 完整的介绍doc上有golang strings docContains, ContainsAny, ContainsRune ContainsRune(s,p)用于查找unicode编码为p的unicode是否在s里面 ContainsAny(s,p)只要满足p中的1个unicode字符在s中即可,Contains需...

2018-03-17 18:26:55 1475

原创 golang防xss注入

golang里面比python处理简单多啦 python处理xss注入攻击 只要用html包就可以了,html.escapeString(content)html.UnescapeString(content)解开和反解的字符相同,都包括’,”,&,<,>这些字符...

2018-03-17 11:52:10 5366

原创 gorm的一些使用技巧和遇到的一个坑

gorm是国内开发者所做的开源golang orm框架,做的比较成熟。 获取方式: go get -u github.com/jinzhu/gorm使用方法查看文档即可,还是比较符合sql语句的写法和设计方式的,当然也支持Raw语句,自己拼出语句去执行。一个小技巧: 查看执行的sql语句,拼了大段的where,find以后想看事实执行的sql是什么,毕竟是开源框架,打出来看看避免自己...

2018-03-17 11:42:01 23984

原创 python防xss注入

什么是xss注入攻击 可以查看这篇文章 其实主要就是转换特定的字符,在某些接口前转换出来或者在前端做处理转换出来,这篇文章只是后端的转换和恢复 转换 quote表示是否要转换引号>>> import cgi>>> cgi.escape('<script>&"', quote=True)'<script&amp...

2018-03-14 09:17:05 5712 3

原创 Go依赖管理工具(四) glide

上一篇 Go依赖管理工具(三)govender 首先澄清一点,这个项目不是android里面的glide,用于图片加载和缓存的那个glide。而是做go package管理的glide 安装方法 go get github.com/Masterminds/glide 使用 glide init/create去创建glide.yaml glide会扫描项目的depende...

2018-03-10 18:26:17 3780

原创 Go依赖管理工具(一)godep

git地址 https://github.com/tools/godep 安装方法 go get github.com/tools/godep 关于GOPATH设置可以参考另一篇文章 GOPATH设置和go get替换HTTPS的技巧 用法 安装好后godep -h查看所有功能 主要讲讲godep save 和 godep restore这两个 godep save...

2018-03-10 18:20:44 3805

原创 学到的一些代码处理的细节

最近写的代码,有同事和mentor review的时候给我提出了一些意见,在这里稍微总结一下。1. 对于同种类型的出错记录,比如增加metrics打点,也尽量将错误类型区分开。不管是来源不同,比如第三方登录的场景,需要将微信,微博出错的打点分开记录,这样方便之后统计第三方调用的出错量,也更容易定位到某个第三方平台的认证服务是否挂掉。还是结果不同,比如对于同一上游请求的处理,返回的错误代码可...

2018-03-10 18:18:19 268

原创 Bosun报警语法

bosun是常用的报警系统,通过配置metrics(items)图可以得到某一个参数在指定时间内的变化,比如设为10s,每隔10s就会去拉这个数据并画图,依据这个图可以实现对某些参数的监控,以此作为报警的依据。 大多数公司的基础架构组都会出一套完备的解决方案,但是核心甚至规则的自定义还是需要bosun语法,因此学习下。基本的就是用q(xxx)来计算metrics图里面值的sum,count,...

2018-03-10 16:33:18 5621

原创 最近工作中接触的几个好用的工具(CANAL,Swagger)

Canal https://github.com/alibaba/canal/ 阿里巴巴的一个监控mysql变化的解决方案,原理其实很简单,Canal Client把自己模拟成mysql的slave,伪装自己为mysql slave,向mysql master发送dump协议,然后master会给slave同步binlog(byte类型),canal本身只支持抽取row-based的改动,可以...

2018-03-10 14:27:22 2503

空空如也

空空如也

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

TA关注的人

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