所有文章¶
Golang源码分析系列之sync.Map底层实现
Golang中sync/map提供了并发读写map功能。这里面分析的源码基于go1.14.13版本。
sync.Map的结构
type Map struct {
mu Mutex // 排他锁,用于对dirty map操作时候加锁处理
read atomic.Value // read map
// dirty map。新增key时候,只写入dirty map中,需要使用mu
dirty map[interface{}]*entry
// 用来记录从read map中读取key时miss的次数
misses int
}
Wireshark抓包分析的几个小技巧
Wireshark是一款强大的抓包分析工具。它支持抓取分析TCP数据段、UDP数据包,应用层协议比如Http、Http2、Https(但不支持Https解密)、gRPC等。这里面列几个我使用过程中的用到的小技巧。
Protocol buffers语法
简介
Protocol Buffers简称Protobuf,是google公司推出的一种数据描述语言。Protocol buffers具有平台无关、语言无关、二进制格式编码、编码后体积小,序列化和反序列化快、类型安全、向后兼容等特点。
Protocol buffers有专门的语法结构来定义数据结构。消息和RPC服务接口是Protocol buffers中两大基本组成。消息类似一个Json object,RPC服务接口定义了服务所具有的接口和所依赖的消息类型。
Protocol buffers定义的数据结构应该保存在.proto后缀名的文件中。目前最新版本的语法协议是proto3。
Go 反射三定律
原文地址:https://blog.golang.org/laws-of-reflection
简介
Reflection(反射) 在计算机中表示程序能够检查自身结构的能力,特别指通过类型进行处理。它是元编程的一种形式,也是最容易让人迷惑的一部分。
类型和接口
因为反射建立在类型系统之上,所以让我们先回顾一下 Go 中的类型。Go 是静态类型语言。每个变量都有一个静态类型,即只有一种类型,并且在编译时就已经确定了。比如int, float32, *MyType, []byte等。比如我们进行如下声明:
Go语言实现简易版netstat命令
netstat工作原理
netstat命令是linux系统中查看网络情况的一个命令。比如我们可以通过netstat -ntlp | grep 8080查看监听8080端口的进程。

netstat工作原理如下:
- 通过读取/proc/net/tcp 、/proc/net/tcp6文件,获取socket本地地址,本地端口,远程地址,远程端口,状态,inode等信息
- 接着扫描所有/proc/[pid]/fd目录下的的socket文件描述符,建立inode到进程pid映射
- 根据pid读取/proc/[pid]/cmdline文件,获取进程命令和启动参数
- 根据2,3步骤,即可以获得1中对应socket的相关进程信息
多网卡模式下Golang应用的流量从指定网卡流入流出方案
最近因业务需要,需要在多网卡模式下实现Go应用的流量从指定网卡流入,请求外网服务时候流量需要从该网卡流出功能。从指定网卡流入很容易实现,只要go应用listen对应网卡即可,但请求外网服务时候就相对麻烦些了。在实践中总结出有三种方案可行。各有优劣。
假定服务器网卡情况如下:
| 网卡 | 网卡IP | 对应的公网IP |
|---|---|---|
| eth0 | 172.31.0.8 | 109.25.48.65 |
| eth1 | 172.31.0.14 | 119.26.38.75 |
实际上我们的服务器使用云服务器,网卡是弹性网卡(eni),绑定的是弹性ip(eip)。三种方案对普通服务器也是能达到目的的。
Golang源码分析系列之Channel底层实现
Golang中Channel是goroutine间重要通信的方式,是并发安全的,通道内的数据First In First Out,我们可以把通道想象成队列。这里面分析的源码基于go1.13版本。
channel数据结构
Channel底层数据结构是一个结构体。
type hchan struct {
qcount uint // 队列中元素个数
dataqsiz uint // 循环队列的大小
buf unsafe.Pointer // 指向循环队列
elemsize uint16 // 通道里面的元素大小
closed uint32 // 通道关闭的标志
elemtype *_type // 通道元素的类型
sendx uint // 待发送的索引,即循环队列中的队尾指针front
recvx uint // 待读取的索引,即循环队列中的队头指针rear
recvq waitq // 接收等待队列
sendq waitq // 发送等待队列
lock mutex // 互斥锁
}
Elasticsearch生产环境配置
Elasticsearch在生产环境部署时候,我们需要考虑系统配置优化和Es本身配置优化,已达到能够发挥其最佳性能。本文是根据官方文档和个人工作实践总结出的生产环境配置。

Elasticsearch内存占用分析与管理
Elasticsearch是基于JVM实现的,内存分配分为堆内(on-heap)和堆外(off-heapp)两部分。每部分的内存,可以用于不同目的的缓存,具体可以看下思维导图:

从整体来看如下所示:

堆内存与堆外内存
一般情况下,Java中分配的非空对象都是由Java虚拟机的垃圾收集器管理的,称为堆内内存(on-heap memory)。虚拟机会定期对垃圾内存进行回收,在某些特定的时间点,它会进行一次彻底的回收(full gc)。彻底回收时,垃圾收集器会对所有分配的堆内内存进行完整的扫描,这意味着一个重要的事实——这样一次垃圾收集对Java应用造成的影响,跟堆的大小是成正比的。过大的堆会影响Java应用的性能。
Java虚拟机的堆以外的内存,即直接收操作系统管理的内存属于堆外内存(off-heap memory),通过把内存对象分配在堆外内存中,可以保持一个较小的堆,可以减少垃圾回收对应用的影响。
