December 31, 2019
使用Dockerfile 多阶段构建Golang 应用
"docker在开发和运维中使用的场景越来越多,作为开发人员非常有必要了解一些docker的基本知识,而离我们工作中最近的也就是对应用的docker部署编排了,小到一个dockerfile, docker-compse文件的编写,大到k8s的管理。这里我们以 golang应用为例讲解一些Dockerfile的基本用法,在ci/cd中经常用到这些知识。\n前提 项目清单:\ndrwxr-xr-x 9 sxf staff 288 12 31 16:13 . drwx------@ 17 sxf staff 544 12 31 14:59 .. -rw-r--r-- 1 sxf staff 14 12 31 16:09 .dockerignore drwxr-xr-x 14 sxf staff 448 12 31 16:21 .git -rw-r--r-- 1 sxf staff 467 12 31 16:08 Dockerfile -rw-r--r-- 1 sxf staff 11 12 31 15:01 README.md -rw-r--r-- 1 sxf staff 84 12 31 …"
November 8, 2019
Golang中的goroutine泄漏问题
"goroutine作为Go中开发语言中的一大利器,在高并发中发挥着无法忽略的作用。但东西虽好,真正做到用好还是有一些要注意的地方,特别是对于刚刚接触这门开发语言的新手来说,稍有不慎,就极有可能导致goroutine 泄漏。\n什么是goroutine Leak goroutine leak 的意思是go协程泄漏,那么什么又是协程泄漏呢?我们知道每次使用go关键字开启一个gorountine任务,经过一段时间的运行,最终是会结束,从而进行系统资源的释放回收。而如果由于操作不当导致一些goroutine一直处于阻塞状态或者永远运行中,永远也不会结束,这就必定会一直占用系统资源。最球的情况下是随着系统运行,一直在创建此类goroutine,那么最终结果就是程序崩溃或者系统崩溃。这种情况我们一般称为goroutine leak。\n出现的问题 先看一段代码:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math/rand\u0026#34; \u0026#34;runtime\u0026#34; \u0026#34;time\u0026#34; ) func query() int { n := …"
October 25, 2019
MySQL8.0中的跳跃范围扫描优化Skip Scan Range Access Method介绍
"在MySQL8.0以前,索引使用规则有一项是索引左前缀,假如说有一个索引idx_abc(a,b,c),能用到索引的情况只有查询条件为a、ab、abc、ac这四种,对于只有字段b的where条件是无法用到这个idx_abcf索引的。这里再强调一下,这里的顺序并不是在where中字段出现的顺序,where b=2 and 1=1 也是可以利用到索引的,只是用到了(a,b)这两个字段\n针对这一点, 从MySQL 8.0.13开始引入了一种新的优化方案,叫做 Skip Scan Range,翻译过来的话是跳跃范围扫描。如何理解这个概念呢?我们可以拿官方的SQL示例具体讲一下()\nCREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2)); INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,1), (2,2), (2,3), (2,4), (2,5); INSERT INTO t1 SELECT f1, f2 + 5 FROM t1; …"
October 18, 2019
一致性哈希算法及其在分布式系统中的应用(推荐)
"摘要 本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及其在分布式系统中的应用。首先本文会描述一个在日常开发中经常会遇到的问题场景,借此介绍一致性哈希算法以及这个算法如何解决此问题;接下来会对这个算法进行相对详细的描述,并讨论一些如虚拟节点等与此算法应用相关的话题。\n分布式缓存问题 假设我们有一个网站,最近发现随着流量增加,服务器压力越来越大,之前直接读写数据库的方式不太给力了,于是我们想引入Memcached作为缓存机制。现在我们一共有三台机器可以作为Memcached服务器,如下图所示。\n很显然,最简单的策略是将每一次Memcached请求随机发送到一台Memcached服务器,但是这种策略可能会带来两个问题:一是同一份数据可能被存在不同的机器上而造成数据冗余,二是有可能某数据已经被缓存但是访问却没有命中,因为无法保证对相同key的所有访问都被发送到相同的服务器。因此,随机策略无论是时间效率还是空间效率都非常不好。\n要解决上述问题只需做到如下一点:保证对相同key的访问会被发送到相同的服务器。很多方法可以实现这一点,最常用的方法是计算哈希。例如 …"
August 31, 2019
Redis 选择hash还是string 存储数据?
"在Redis中存储数据时,经常使用string和hash这两种类型,至于这两者有什么不同,底层实现有何区别,推荐参考: https://segmentfault.com/a/1190000019552836"
August 13, 2019
一文理解MySQL中的page页
"在介绍InnoDB中的页的时候,很有必要先让大家了解一下InnoDB中的存储结构\n从InnoDB存储引擎的逻辑结构看,所有数据都被逻辑地存放在一个空间内,称为表空间(tablespace),而表空间由段(sengment)、区(extent)、页(page)组成。 在一些文档中extend又称块(block)。\n一、表空间(table space)\n表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间等。\n在 InnoDB 中存在两种表空间的类型:共享表空间和独立表空间。如果是共享表空间就意味着多张表共用一个表空间。如果是独立表空间,就意味着每张表有一个独立的表空间,也就是数据和索引信息都会保存在自己的表空间中。独立的表空间可以在不同的数据库之间进行迁移。可通过命令\nmysql \u0026gt; show variables like \u0026#39;innodb_file_per_table\u0026#39;; 查看当前系统启用 …"
August 12, 2019
一列说明数组与Hash效率的区别到底多大
"在数组中添加 10000 个元素,然后分别对这 10000 个元素进行检索,最后统计检索的时间。\n数组Array\nimport time # 插入数据,数组 result = [] for i in range(10000): result.append(i) # 检索数据 time_start=time.time() for i in range(10000): temp = result.index(i) time_end=time.time() print(\u0026#39;检索时间\u0026#39;, time_end-time_start) 运行结果:\n检索时间为 1.2436728477478027 秒。\nHash哈希\nimport time # 插入数据 result = {} for i in range(1000000): result[i] = i # 检索数据 time_start=time.time() for i in range(10000): temp = result[i] time_end=time.time() print(\u0026#39;检索时 …"
July 29, 2019
kubernetes dashboard向外网提供服务
"目前新版本的 kubernetes dashboard ()安装了后,为了安全起见,默认情况下已经不向外提供服务,只能通过 http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ 本机访问。在我们学习过程中,总有些不方便,这时我们可以利用 kubectl proxy 命令来实现。\n首先我们看一下此命令的一些想着参数\n➜ ~ kubectl proxy -h To proxy all of the kubernetes api and nothing else, use: $ kubectl proxy --api-prefix=/ To proxy only part of the kubernetes api and also some static files: $ kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/ The above lets you …"
July 28, 2019
RabbitMQ常见面试题
"RabbitMq的消息类型(6种)、 消息确认机制\nRabbitMq中的概念及解释\nServer(Broker): 接收客户端连接,实现AMQP协议的消息队列和路由功能的进程; Virtual Host:虚拟主机的概念,类似权限控制组,一个Virtual Host里可以有多个Exchange和Queue。 Exchange: 交换机,接收生产者发送的消息,并根据Routing Key将消息路由到服务器中的队列Queue。 ExchangeType: 交换机类型决定了路由消息行为,RabbitMQ中有四种类型Exchange,分别是fanout、direct、topic 和 headers; Queue:消息队列,用于存储还未被消费者消费的消息; Message:由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、优先级是多少、由哪个Message Queue接收等;body是真正需要发送的数据内容; BindingKey:绑定关键字,将一个特定的 Exchange 和一个特定的 Queue 绑定起来。 2.对mq有哪些理 …"
July 28, 2019
rabbitmq消息队列的消息持久化机制
"首先阅读这篇文章: https://blog.csdn.net/yongche_shi/article/details/51500534\n之前其实已经写过一篇关于RabbitMQ持久化的 文章 ,但那篇文章侧重代码层面的写入流程,对于持久化操作何时发生以及什么时候会刷新到磁盘等问题其实都没有搞清楚,这篇文章着重于关注这些问题。\n消息什么时候需要持久化? 根据 官方博文 的介绍,RabbitMQ在两种情况下会将消息写入磁盘:\n消息本身在 publish 的时候就要求消息写入磁盘; 内存紧张 需要将部分内存中的消息转移到磁盘; 消息什么时候会刷到磁盘? 写入文件前会有一个Buffer,大小为1M(1048576),数据在写入文件时,首先会写入到这个Buffer,如果Buffer已满,则会将Buffer写入到文件(未必刷到磁盘); 有个固定的刷盘时间:25ms,也就是不管Buffer满不满,每隔25ms,Buffer里的数据及未刷新到磁盘的文件内容必定会刷到磁盘; 每次消息写入后,如果没有后续写入请求,则会直接将已写入的消息刷到磁盘:使用Erlang的receive x after 0来实 …"