版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 引言 人们在潜意识里,总会觉得复杂且精巧的东西是好东西。但是这个复杂这个词在软件架构设计中,却不一定是好事情。因为过于精巧和复杂的系统往往意味着系统更难以维护,出现问题后,故障更难排查。萌叔前段时间在阅读和分享RocketMQ的过程中,发现它有很多设计非常的简单粗暴,堪称”暴力美学”的典范,同时又给人眼前一亮的感觉(还能这么玩)。 1. NameServer高可用 在RocketMQ的架构体系中,NameServer的作用类似于注册中心,Broker会周期性的向NameServer发送心跳,注册Topic信息。Producer和Consumer会向NameServer查询某个Topic的路由信息(Topic位于哪个Broker) Topic路由信息 { “OrderTopicConf”: “”, “queueDatas”: [{ “brokerName”: “broker-3”, “readQueueNums”: 4, “writeQueueNums”: 4, “perm”: 6, “topicSynFlag”: 0 }, { “brokerName”: “broker-4”, “readQueueNums”: 4, “writeQueueNums”: 4, “perm”: 6, “topicSynFlag”: 0 }], … } 如上面所示,某个Topic位于broker-3和broker-4,每个Broker上有4个MessageQueue 那么如何保证部分NameServer实例宕机后,注册中心的功能仍然能够正常运转呢? 按照正常点的想法,肯定是NameServer分成Master和Slave,然后Master和Slave之间在加上数据同步,如果Master宕机了,只要进行主从切换即可。这种做法肯定没问题,毕竟Hadoop中的NameNode也就是这么做的。 RocketMQ中的实现要简单的多,每个NameServer相互独立,并且它们之间没有通信。Broker会向每一个NameServer、NameServer1、NameServer2等等发送心跳,心跳中包含有它所维护的每个Topic的信息),这样每个NameServer就都含有路由信息。 等到Producer和Consumer向NameServer查询路由信息时,它会尝试向每一个NameServer进行请求。… 继续阅读 RocketMQ架构设计中的”暴力美学”(1)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 萌叔工作十多年,有不少服务调优的经验,在这里整理一下思路。希望对自己和同行有所帮助。 1. 发现问题 1.1 发现问题比解决问题难度更大 找出系统瓶颈和问题难度很大,一般只要能够找出且能够稳定复现,问题都能够被解决。 1.2 压测能够帮我们发现系统瓶颈,找出问题 压测不仅可以帮助我们发现系统瓶颈,还能用于发现死锁问题 1.3 尽可能细粒度的监控指标对发现问题帮助很大 讲几个容易忽略的细节 使用Cache的场景,要留意Cache的命中率 使用Channel的细节,要监控channel的长度,注意Channel是否写满,阻塞其它协程 对于比较复杂的接口,如果延迟高,需要有tracing记录,关注到底是那个环节耗时过多 对于MQ和数据库的场景,甚至还需要监控PageCache的命中率和使用情况、磁盘IO等等 GC 的耗时(特别是Java中Full GC) 2. 常见的思路 2.1 绝大多数服务的系统瓶颈是IO 我们接触到的绝大多数服务,都是IO型服务,影响延迟的主要因素是IO,磁盘IO、网络IO,数据库、微服务的响应延迟等等 2.2 如果CPU是瓶颈,需要有火焰图,关注是哪个环节消耗的CPU过多?每个部分占比是否合理?(注意压测) 比如是否大量的CPU时间被消耗在了锁竞争、上下文切换、垃圾回收、调度等。 在Golang中,由于锁中含有自旋锁,如果对锁的竞争激烈,会有大量的CPU时间被消耗在锁上。 在Golang中,P设置不合理也会导致大量的上下文切换 见文章 GOMAXPROCS你设置对了吗? 2.3 某一类型的服务,往往会有一组需要额外注意的核心指标 某些特定的服务容易受到特定因素的影响,比如 基于模型的分类器,压测时要特别关注它的CPU使用率是否能够跑满 见文章 AI预测模型工程化性能调优 数据库服务要留意磁盘IO 2.4 GC… 继续阅读 服务调优经验总结

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 萌叔使用WordPress + Markdown的组合方式写blog已经有好几年了。在这篇文章中,笔者将会分享一些我曾经或者正在用的WordPress插件。 2. 插件 2.1 WP HyperMD Markdown编辑器,至今运行良好 对萌叔而言,用Markdown写文章写得更快,且不必要专注样式细节,而专注于内容本省。 2.2 Akismet Anti-Spam 反垃圾评论的,很好用 2.3 Cool Tag Cloud 一个简单但非常漂亮的标签云 效果如下图 2.4 Google XML Sitemaps 站点地图生成器,提高SEO效果。友情提示,别忘了将站点地图的地址提交给常用的搜索引擎。 本站的站点地图URI sitemap 2.5 Login LockDown 防止恶意程序采用暴力登录的方式,攻击网站。它的原理,如果来自某个IP的用户,在5分钟内连续3次登陆失败。将会禁止在未来的1个小时内,禁止来自这个IP的登录行为。 这个插件,萌叔非常推荐。如果你细心观察访问日志,来自互联网的恶意登录(主要是基于密码字典)非常普遍,使用Login LockDown可以增大恶意程序的攻击难度。另外建议用户名不使用”admin”、”root”, 密码一定使用强密码。 2.6 NoSpamNX 保护博客免受自动垃圾评论机器人的侵扰 2.7 WordPress… 继续阅读 那些年我用过的WordPress插件

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 之所以写这篇文章是因为我已经在不止一个群里,看到有人问如何在ES中存储关联关系。 2. 答案 你可能会在网上看到有说Join datatype和Nested data type的,但是其实这都不是ES该有的玩法。 Join datatype和Nested data type都会涉及多次查询的开销 Join datatype本身的数据就是在不同的表中,对于分布式数据库,还涉及数据从不同的节点上拉取和组装的开销。 那么应该怎么做?答案就是用冗余的宽表来存储关联关系 举例说明 假如我需要在ES中存储的实体有书籍、书籍有作者信息、书名等等信息,显然实体之间有如下关系 如果在传统的关系型数据库中,就需要创建2张表,一张表表示作者,一张表代表书。但是对于nosql数据库,只需要一张表(书)即可,doc结构形如: { “name”:”zhangsan”, “publisher_identifier”: “xxx-xxxx-xxx” “author”:{ “name”: “jobs”, “phone”: “111111111” } } 作者信息作为书的属性存储在一起,放一个doc中即可。 这样的做法必然是会带来数据冗余,但是以空间换时间,查询速度就有了保障。 现代的nosql数据库大多应对的海量数据的存储查询的问题,因此大都是分布式结构。在这种情况下,整体的设计方案必须足够简单,才能够易于维护和扩展。同样的做法,也完全适用于HBase。 3. 说几句某些人可能不爱听的话 ES集群的使用成本其实是很贵的,用了就别怕贵,觉得烧钱就别用 ES自身的性能优化工作做得还是很好的,对大多数人而言,不需要考虑优化,性能不够,就老老实实的加硬件就行。高版本相比低版本性能和稳定性都有很大的提升,优先考虑高版本 SSD对ES的性能提升非常明显(便宜不一定不是好货,但好货一定不便宜) 4. 参考资料 1.Join… 继续阅读 elasticsearch如何存储关联关系?

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 萌叔最近做一个类似1password的命令行密码管理工具passwordbox。传送门: vearne/passwordbox 支持使用对象存储进行多端同步(可选),目前支持阿里云OSS,青云QingStor 内部实现细节 首先将每个记录项加密存储在SQLite的数据文件中,然后再对整个数据文件进行二次加密。记录在内存中也是以密文的形式存在,安全系数比较高。 快速开始 编译 make build 安装 make install 启动 pwbox –data=/Users/vearne –data 设置加密数据文件的存储路径 建议你为passwordbox设置一个别名 alias pwbox=’pwbox –data=/Users/vearne’ 程序启动以后,按照导引的要求创建数据库,所有的记录项都存储在数据库中 ─$ ./pwbox –data /tmp/ —- login database —- ? Please type database’s name: test fullpath /tmp/6879630a7d56210d2cd2491cb99d781194689fed71d7890a8dabbcb3a678cb73 ? Database is… 继续阅读 密码管理工具(命令行)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.引言 产品要求的功能都都开发完了,但这并不是终结。怎么样做才能让我们的服务具有更好的质量。 笔者结合自己的遇到的问题和工作中的经验,并以提问的方式,给读者一点点建议 2. 提问 重要性不分先后 2.1 如果服务器重启,服务是否能自动拉起? 2.2 如果程序异常退出,服务是否能够自动拉起? 2.3 如果程序异常退出,能够自动拉起,那么你怎么知道服务是否发生了重启? 2.4 如果是web服务,QPS是多少?每个URL的QPS是多少? 峰值是多少?一般在什么时间点触发? 每种URL的请求量是否合理? 2.5 如果是web服务,每个请求的响应时间是多少?TP90?TP99分别是多少? 2.6 异常请求(比如HTTP非200的比例是多少?)什么样的比例是合理的?为什么? 2.7 如果是多实例部署,那么整个系统的承载极限是多少?如果达到了极限,瓶颈在哪儿(木桶原理中所谓的短板) 2.8 服务都有哪些依赖项(微服务/数据库/文件系统) 其中哪些是无状态的,哪些是弱状态的,哪些是强状态的。这些外部服务和系统,是否已经做到高可用?能否做到快速扩容? 2.9 服务消耗的带宽多少?是否有可能达到带宽上限 如果是面向公网的服务,请求是否已经进行了压缩? 2.10 服务在部署上,是否已经做到了二地三机房 每个地区的网络线路,是否能做到2套或2套以上 (防止光纤被挖断的情况) 2.11 DNS服务是否能够对后端服务进行探活,自动修改域名的解析列表 2.12 部署是否实现了自动化 如果服务需要紧急扩容,该怎么做? 基于docker的容器化方案,还是ansible脚本? 2.13 文档是否完整,文档是否能与代码保持一致 2.14… 继续阅读 开发更高质量的服务

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 引言 我买的雷蛇的机械键盘,采用了1年半,坏了,先坏了F键,又坏了空格键和回车键,果然便宜没好货啊。买了几个cherry的轴体,本着人道主义精神再最后挽救一下。 2. 准备工作 2.1 cherry轴体 某宝上就有卖,红轴、茶轴、青轴3元/个,绿轴6元/个。 从阻尼的感受来看,从轻到重分别是红、棕、青(图上蓝色的那个)、绿 亲身的体验还是很重要的,可以各买1个试试,或者直接购买试轴器 轴体拆开了,就是下图这么个样子,外壳、铜片、弹簧、塑料的按键 不包含任何芯片,看起来原理也简单,但却真正考验配件的质量 2.2 电洛铁套装 2.3 螺丝刀套装 只用到一字和十字螺丝刀 2.4 拔轴器 因为笔者没有购买,这里直接用网上的图 3. 动手 3.1 拆除前置面板 注意 前置面板上有大量的卡扣,拆的时候要有耐心,用一字螺丝刀,一点点的撬开。 3.2 拆除后面板 注意 有几颗螺丝其实是隐藏在键盘的胶皮垫子下方,拆除时,不要忘了。 3.3 拆除原来的轴体 拆除轴体需要注意的以下事项 1) 电洛铁加热到足够温度,首先沾少量的松香,再融开焊点的锡 此处松香作为助焊剂,沾松香可以使电洛铁更好的吸附焊点的锡,俗称挂锡。 2)待焊点的锡清除的差不多时,一边融开焊点的锡,一边可以使用拔轴器摁住轴体的卡扣(一字螺丝刀按住卡扣慢慢撬也可),向外慢慢的拔 注意 轴体有两侧有卡扣不能硬拔,否则可能损坏PCB板 小技巧 如果旧轴体已经拔出,但是PCB板的孔洞没有露出,可以一边用电洛铁融开焊点,一边用细铁丝(曲别针即可)插入小孔反复抽插。这样可以使孔洞露出。… 继续阅读 机械键盘换轴记

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 絮絮叨叨 自从把我的博客从CSDN迁出,独立成站以后,就很少在微信上发技术文章了, 主要是2个原因: 阅读微信的都是碎片时间, 而技术文章很多都需要深度的思考,不少还需要动手实际操作 在微信上粘贴代码太不放方便了 最后 欢迎访问我的个人博客 萌叔 今天来聊点最近的一些感受。 1. 中国崛起 我曾经跟我的同事们开玩笑,我说以后外国程序员,都必须要学中文,不然他们就看不到第一手的技术资料。 这几年中国程序员在世界上的影响力越来越大,这可能得益于中国有最大的互联网消费群体。 举几个例子 中国有世界上最大的redis使用平台,据新浪公布的资料,他们的redis平台有500+server,2000+的实例,不过这个应该不是单个集群的规模。 golang虽然是Google开发的语言,但是最大golang社区在中国,从几届gopher china大会的热闹程度,就可以看出golang在中国的火热程度 在前端领域巨牛的开源JavaScript项目VUE.js,为Github有史以来星标数第10多的项目,其作者是中国的尤雨溪 2. 处理能力压倒实际需求 曾经和一个美发行业的朋友聊过天,他所在的公司是一家有将近10余家分店的连锁企业,可是每天产生的订单数不超过1000单。 所以我的感觉是对绝大数领域,社区存在的解决方案的处理能力足够满足需要,数据库、或者某些框架只需要做简单的配置,就能够满足他们的日常需要了。二次开发,尤其是性能领域的二次开发的重要性变得相对较低。 3. 成熟的解决方案层出不穷 在10年前,甚至是几年前,技术资料非常难找。很多问题都没有很好解决方案,问都不知道该问谁。而现在各种社区里有各种乐于回答问题的好心人。各种开源或者收费云服务的解决方案满大街都是。 举几个例子 电商你可以用ShopsN 日志收集可以用ELK(elasticsearch + logstash + kibana) 监控你可以用zabbix或者open-falcon 这些方案很多都是开箱即用,就像使用yum或者apt-get一样简单。 而且应对绝大多数场景,已经绰绰有余。真正需要进行二次开发的只剩下扳着指头都能数出来的寥寥几家。 我不禁有些担忧,我们这些程序员的出路在哪儿。 总结 絮絮叨叨的说点心里话吧,也想听听大家的吐槽。 请我喝瓶饮料

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 在分布式环境中,生成全局唯一ID是非常需求。本文将介绍几种常见生成方法,并对它们的优缺点做出点评。 0. 8个字节 语言或数据库 内建类型 Golang uint64 Java long Python int MySQL bigint unsigned 2 ^ 32(4个字节)最多只有40多亿,对于高并发的系统,肯定不是够的。 以新浪微博为例,每天的新增的微博量都过亿,所以考虑到ID的容量,这个ID的长度至少是8个字节 1. UUID 长度: 为16 bytes, 128 bits 44e91a8a58d111e8ae84784f43a6cab8 见参考资料1: 5种版本 1. 时间的版本 2. DCE Security 3. MD5哈希 4. (伪)随机数 5. SHA-1哈希 以Version… 继续阅读 如何生成全局唯一ID