实战
weixin_41571449
这个作者很懒,什么都没留下…
展开
-
元数据管理的必要性
工作中的一点体会通常业务初期,为了快速实现需求,对某一业务实体,会疯狂新加字段。常见的方式是搞一个大map,什么都往里面塞。短期内收益确实比较明显开发快,能够迅速解决新需求和业务实体的绑定关系,可以快速引入新feature维护成本低,只需要维护一个服务的稳定性即可但是长远看是个潜在的雷点并发问题写覆盖,多个写入方难以保证原子性相互覆盖,如果牵扯到跨机房同步,冲突解决很困难数据模型不清晰,后期瘦身极其困难数据的定义不清晰,废弃字段过大但又无法清理,删除又容易引入问题业原创 2020-10-27 21:37:06 · 638 阅读 · 0 评论 -
跨机房环境下常见的唯一键处理方式
当业务发展到一定程度,出现了跨机房的时候,我们往往会面临历史原因中一些唯一键的处理,有些是自增键,有些是C端设置的,本问探讨下怎么解决这个问题数字键常见于db的自增主键或用户生成时的随机id对于自增主键这种毫无业务含义的字段,通常采用id生成器进行替换,一般团队都会有通用的id生成器,方法一般也是基于比较主流的id生成算法,可以参考id生成器对于用户生成时的随机id,一般就具有了一些业务id,比如该id可以用于应用中的搜索添加好友等(比如QQ号),这种情况下,id生成器这种会生成长id的工具就不能满原创 2020-08-15 14:57:46 · 288 阅读 · 0 评论 -
代码行数统计
最近做一些批量化的改造,需要预估团队整体工作量。因为按业务本身复杂度来统计需要熟悉所有代码,执行上很难操作,因此用代码行数来评估工作量研究了几种工具和方法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 · 582 阅读 · 0 评论 -
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 · 164 阅读 · 0 评论 -
golang微服务的设计架构
最近看了现在公司的golang代码架构,再结合golang的语言特性和现有包管理的局限性,觉得有些不合理。想在接下去技术改造过程中调整一下。写出来,如果大家有什么好的意见和建议希望和我探讨一下。首先,既然是微服务,应该是尽量解耦合的。可以允许有工具类,但是不可以有一个巨大的common包,里面不能带有对其他微服务依赖的逻辑,不然这个包一更新会给所有微服务造成测试压力。对于工具类,与其集中在一...原创 2018-04-06 17:28:30 · 5252 阅读 · 0 评论 -
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 · 2208 阅读 · 1 评论 -
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 · 6762 阅读 · 0 评论 -
代码设计的注意点
总结一下最近工作中体会到和学到的点虽然要求快速迭代,比如说python开发下,还是要注意代码的扩展性,不能为了快速上线牺牲掉代码扩展性,能封装的尽量封装成类,然后再把他当基类去扩展,短期内不明显,但长期以来肯定是有好处的,比如dao层,通常只会使用一种orm框架,所以支持的增删改查模式都是一样的,就可以自己扩展,做一些get_or_create,update_if_exist之类的封装,这样...原创 2018-03-25 11:52:41 · 556 阅读 · 0 评论 -
goland合并branch技巧
可以用goland,pycharm,intellij等idea方便地去合并代码。这里用goland举个例子,pycharm和intellij是更成熟地ide,功能只会更加强大。 随便找个项目,以go-redis为例子好了。我建两个分支,test和test2 然后分别在两个分支上做些改动。这里仅仅为了举例,改动毫无意义。 这样,test改动command相关的文件,test和test2同时...原创 2018-04-07 19:46:31 · 8160 阅读 · 0 评论 -
python防xss注入
什么是xss注入攻击 可以查看这篇文章 其实主要就是转换特定的字符,在某些接口前转换出来或者在前端做处理转换出来,这篇文章只是后端的转换和恢复 转换 quote表示是否要转换引号>>> import cgi>>> cgi.escape('<script>&"', quote=True)'&lt;script&...原创 2018-03-14 09:17:05 · 5642 阅读 · 3 评论 -
pdb调试python代码
本来只知道可以用pycharm,eclipse这类东西打断点。今天同事告诉我才知道原来python本身也有工具pdb,这个名字应该来自c语言的gdb吧=。=使用很简单,import pdb即可,在需要开始断点的地方加上 pdb.set_trace()即可。调试中命令b 打断点,常用于循环,这样下次循环可以在此处停住 c 继续执行直到下一个断点 l ...原创 2018-03-20 00:46:22 · 292 阅读 · 0 评论 -
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 · 1433 阅读 · 0 评论 -
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 · 188 阅读 · 1 评论 -
项目中错误类型的定义和思考
现在开发业务都是微服务,api调用rpc,rpc之间互相调用。除了常规的链接失败或超时以外,还有很多业务上的错误。为了使返回的错误码容易判断和查错,通常会靠一个统一定义的错误代码映射表。其实我们平时http的各种错误码也就是一个映射表。 有一种做法是代码里写死一个映射表文件,每次有新增去修改这个文件。但是当系统渐渐变大。业务可能会按模块进行拆分并接耦合,业务之间可能只是一个对接,代码repo...原创 2018-05-26 21:55:09 · 732 阅读 · 0 评论 -
热门缓存的实现方式
做社交过程中,常常会有一些热门的用户,内容等等。我了解到的基本有两种实现方式,里面也有些细分 1. 给热门用户内容专门建一个redis, a.每次出现热门用户,内容,可以由运营操作给通过在运营平台给用户或内容加热,加到redis里面。 b.在现有的计数缓存里加额外的计数,对于获赞数或者评论数频率做个统计,每隔两分钟清一下,两分钟内超过100赞就自动mark成热门内容加入red...原创 2018-06-18 23:08:07 · 335 阅读 · 0 评论 -
常见qps限制方式
生产环境经常会跑一些离线任务,或者有一些异步任务在问题恢复后积压需要放水,此时我们需要控制对下游的访问qps,避免打挂下游,有多种方式去实现。当你是一个单进程/单携程通常是一些小的回扫任务,多用于处理临时任务。因为是单个进程/携程,简单的话可以首先time.Sleep()较长一段时间,同时打一下执行时间的大概日志,然后根据实际调用下游的时间,估出一个值调整下游的qps。如果下游超时不稳定有尾...原创 2019-09-07 21:21:57 · 10166 阅读 · 0 评论 -
业务实现中的本地缓存(GO)
实际业务实现中常常会使用到本地缓存,用以减少对实际存储的访问,我们会针对不同的使用场景设计不同的缓存模式,但是基本的实现方式都是一个巨大的Map/Table(不同语言)。下面用go来说,总体的实现都是通过一个,根据不同的需求,LFU,LRU再设计map里面具体的entry的struct,保存需要的计数用来做淘汰,下面从不同使用角度来说明一下普通的保存配置项的本地缓存实际使用中,某些中台服务/服...原创 2019-09-01 17:29:34 · 2869 阅读 · 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 · 3594 阅读 · 5 评论 -
用嵌套的两个kafka实现突发性高并发consumer
今天遇到一个问题,某个kafka comsumer特别耗时,排查发现,之前把一些操作写成串行了,但是这个comsumer属于那种来一波消息就中断的,改成并行的又需要大量资源(CPU/MEM),不划算。后来同事提供了一种思路,将并行的操作拆另一个comsumer里用一个进程分个处理,这样前一个comsumer可以及时消费掉,并且不耗费资源,后一个comsumer串行地处理就不会有很长的耗时,解决了...原创 2018-09-29 01:34:47 · 523 阅读 · 0 评论 -
用go-wrk,go-torch做服务器压测和性能分析
常常会有这样的场景,写了一个接口,上线发现性能不大好,费资源处理慢,可能是某个rpc耗时长,可能是可以并发的地方没有做并发,但发现问题比较麻烦,最好能有一些可视化的工具。当然我们能这么做,是因为go语言集成了profile采样工具,并且允许我们在程序的运行时使用。准备工作写个最简单的web server,一个helloworldpackage mainimport ( ...原创 2018-09-09 21:37:40 · 2807 阅读 · 1 评论 -
golang防xss注入
golang里面比python处理简单多啦 python处理xss注入攻击 只要用html包就可以了,html.escapeString(content)html.UnescapeString(content)解开和反解的字符相同,都包括’,”,&,<,>这些字符...原创 2018-03-17 11:52:10 · 5315 阅读 · 0 评论 -
gorm的一些使用技巧和遇到的一个坑
gorm是国内开发者所做的开源golang orm框架,做的比较成熟。 获取方式: go get -u github.com/jinzhu/gorm使用方法查看文档即可,还是比较符合sql语句的写法和设计方式的,当然也支持Raw语句,自己拼出语句去执行。一个小技巧: 查看执行的sql语句,拼了大段的where,find以后想看事实执行的sql是什么,毕竟是开源框架,打出来看看避免自己...原创 2018-03-17 11:42:01 · 23850 阅读 · 0 评论 -
代码入口控制方式
有很多app其实都做了国际版,但是国际版和国内版都用了相同的code base,不同国家地区对某些协议和用户分级包括审核的要求都不同,走的分支就不同了。 那么如何区分这些分支呢?middleware传参客户端的middleware上带有app_id或者类似的字段,rpc层拿到ctx的时候去获取一下app_id,然后根据app_id判断国际国内版,然后去走不同的分支服务器环境变量部原创 2018-02-05 09:32:42 · 383 阅读 · 0 评论 -
微服务服务端架构
微服务正在成为软件开发主流,配合上container和kubernetes,我们可以实现服务在云平台的快速上线和滚动升级。 楼主所在公司是这样的服务端架构: httpapi层:客户端的调用入口,这些服务直接暴露给客户端,主要会调一些中间件,这一层几乎没有复杂逻辑,是一些实质性功能的入口。 中间层:因为微服务很分散,而客户端请求可能需要调用多个服务才能完成,因此产生了中间层,这里面包含较为复杂原创 2018-02-05 01:35:21 · 907 阅读 · 0 评论 -
linux查找文件find和grep
在linux下我们往往需要查找文件或查找文件下的内容,可以使用find和grep命令 先从入门开始入门便捷使用如我要在一个目录下查找所有路径中带有user的目录或文件,我只要find . -name "user*"./user-ops./user-ops/target/user-ops-0.1.jar.original./user-ops/target/user-ops原创 2018-01-26 01:03:29 · 357 阅读 · 0 评论 -
关于python kafka一些配置
Kafka是我们常用的消息队列,python kafka库可以实现Producer和Comsumer,相关资料一查一大把,我们今天来讲讲一些特别的配置和注意事项Producerapi_version,使用的时候最好指定api_version,(0,9)或者(0,10)之类的,不然容易发生编码错误传不出去producer.send()时候可以带上key 这个optional的参数,效果是原创 2018-01-25 01:02:46 · 2585 阅读 · 0 评论 -
python优化分析工具
除了上次介绍的内置的一些方法外内置方法和系统方法 还有很多工具line_profilerpip install line_profiler安装 需要在被测的函数前加上@profile,还是用上次的堆排程序试一下wujingcideMacBook-Pro:test wujingci$ kernprof -l -v dp.pyWrote profile results to dp原创 2018-02-01 01:08:23 · 633 阅读 · 0 评论 -
charles实现app调试
前提手机和本地服务器接的同一个网,不然无法识别内网地址进行转发1.安装charles并信任根证书 2.添加代理的网站 3.设置map规则,将对app的访问map到本地server而不是在线服务器上 4.手机配置代理 在charles上选择 弹出窗口告诉你配置的代理。 这时候进入手机配置(iphone为例),连上wifi后,点进你连上的无线网,拖到底配置代理,手动配上弹出原创 2018-01-24 01:57:07 · 3936 阅读 · 0 评论 -
Python处理mysql特殊字符
有的时候我们会去扫表,然后拿出扫的结果再到另一张表里去查信息。比如下面一段index_sql_str = "select %s from user where %s = %d" % ("social_id", "user_id", u_id) db_cursor.execute(index_sql_str) rows = ['"' + row[0] + '"' for row原创 2018-01-31 11:08:51 · 2667 阅读 · 0 评论 -
linux进程后台运行方法归纳
nohup nohup [command] >filename 2>&1 &setsid setsid ping www.ibm.com 原理是用init进程做父进程disown针对已经启动的job 用disown -h jobspec来使某个作业忽略HUP信号。 用disown -ah 来使所有的作业都忽略HUP信号。 用disown -rh 来使正在运行的作业忽略HUP信号。原创 2018-01-31 01:23:12 · 391 阅读 · 0 评论 -
nsq实现逻辑有序
nsq本身是无序的,如果起多个consumer消费可能会顺序混乱。但实际工作中有这种场景,比如用户更新数据,需要保证两次更新的先后顺序。 因此想到了用队列实现,建100个队列起100个线程去处理,nsq的consumer只做最简单的操作,这里做的是拿到message,用user_id对100取模,放进相应的队列里,然后等到队列处理完成再手动提交避免重复消费.# -*- coding: utf原创 2018-01-22 22:36:33 · 3809 阅读 · 0 评论 -
python 装饰器/Cprofile计算函数执行时间
用简单的堆排序来查看这些工具 今天先看一些内建工具自己写一个装饰器注释掉的部分是将尾递归省略掉的方法,理论上会提升效率,我用来做比较的wujingcideMacBook-Pro:test wujingci$ cat dp.py# encoding: utf-8import randomfrom functools import wrapsimport timede原创 2018-01-29 02:09:54 · 1157 阅读 · 0 评论 -
golang操作redis
golang操作redis主要有两个库, github地址 redigo redis区别是redigo类似于一个redis_cli的client,执行各项命令都用Do函数去做. redis则将各种操作封装成函数了 个人倾向于redis,redigo执行命令过于繁琐了,初接触用Do方法执行命令容易出错,比如range里面的返回的整型数都要用string类型的,让我觉得有些困扰起cli...原创 2018-03-03 17:05:12 · 2890 阅读 · 0 评论 -
python操作redis
python操作redis,用redis库。安装pip install redis使用建立连接池并取出连接>>> import redis>>> pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)>>> r...原创 2018-03-03 15:26:17 · 439 阅读 · 0 评论 -
etcd和redis的比较和日常使用场景
个人观点:etcd的红火来源于kurbernetes用etcd做服务发现,而redis的兴起则来源于memcache缓存本身的局限性。 etcd是一种分布式存储,更强调的是各个节点之间的通信,同步,确保各个节点上数据和事务的一致性,使得服务发现工作更稳定,本身单节点的写入能力并不强。 redis更像是内存型缓存,虽然也有cluster做主从同步和读写分离,但节点间的一致性主要强调的是数据,并不...原创 2018-03-03 12:38:29 · 31789 阅读 · 1 评论 -
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 · 3740 阅读 · 0 评论 -
学到的一些代码处理的细节
最近写的代码,有同事和mentor review的时候给我提出了一些意见,在这里稍微总结一下。1. 对于同种类型的出错记录,比如增加metrics打点,也尽量将错误类型区分开。不管是来源不同,比如第三方登录的场景,需要将微信,微博出错的打点分开记录,这样方便之后统计第三方调用的出错量,也更容易定位到某个第三方平台的认证服务是否挂掉。还是结果不同,比如对于同一上游请求的处理,返回的错误代码可...原创 2018-03-10 18:18:19 · 240 阅读 · 1 评论 -
Bosun报警语法
bosun是常用的报警系统,通过配置metrics(items)图可以得到某一个参数在指定时间内的变化,比如设为10s,每隔10s就会去拉这个数据并画图,依据这个图可以实现对某些参数的监控,以此作为报警的依据。 大多数公司的基础架构组都会出一套完备的解决方案,但是核心甚至规则的自定义还是需要bosun语法,因此学习下。基本的就是用q(xxx)来计算metrics图里面值的sum,count,...原创 2018-03-10 16:33:18 · 5411 阅读 · 0 评论 -
最近工作中接触的几个好用的工具(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 · 2468 阅读 · 0 评论 -
linux文件计数,删除小技巧
删除改动在20分钟之前的文件常用于清logfind . -type f -mmin +20 -exec rm {} \;查看文件中出现的行数可用于快速计数,下面grep -rni db_error | wc -lcat error.log |grep -i 'db_error:' |wc -l less处理大文件对于大文件,比如日志,如果只需要查看些内容分析,原创 2018-02-07 01:30:20 · 291 阅读 · 0 评论