初识Golang汇编
0. 为什么写本文在分析go的某些特性底层功能实现时发现:很多跟runtime运行时有关,而要掌握这一部分的话,有一道坎是绕不过去的,那就是Go汇编。索性就查阅了一些资料,在阅读之余整理总结了一下,并分享给大家。
(本文使用Go版本为 go1.14.1)
1. 为什么需要汇编众所周知,在计算机的世界里,只有2种类型。那就是:0和1。
计算机工作是由一系列的机器指令进行驱动的,这些指令又是一组二进制数字,其对应计算机的高低电平。而这些机器指令的集合就是机器语言,这些机器语言在最底层是与硬件一一对应的。
显而易见,这样的机器指令有一个致命的缺点:可阅读性太差(恐怕也只有天才和疯子才有能力把控得了)。
为了解决可读性的问题以及代码编辑的需求,于是就诞生了最接近机器的语言:汇编语言(在我看来,汇编语言更像一种助记符,这些人们容易记住的每一条助记符都映射着一条不容易记住的由0、1组成的机器指令。你觉得像不像域名与IP地址的关系呢?)。
1.1 程序的编译过程以C语言为例来说,从hello.c的源码文件到hello可执行文件,经过编译器处理,大致分为几个阶段:
编译器在不同的阶段会做不同的事情,但 ...
我眼中的C语言及其起源
0. 为什么写这篇文章一直想写一篇关于C语言的文章,里面包含C语言的发展史、创始人等相关事迹。但是却迟迟未写,主要原因是因为:在我看来,这个语言太过于伟大、耀眼。作为一个仅仅使用过C语言的普通开发来说,完全没资格去写。但是,最近在看过一篇丹尼斯.里奇写的《C语言发展史》之后,坚定了我写这篇文章的决心。不是歌功颂德,仅仅是以一种客观的视角去欣赏。
1. C语言发展史任何一种新事物的出现都不是来自于偶然,而是时代所驱使的必然结果。
1.1 C语言有多伟大如果你问我:C语言有多伟大。那么,我可能会想一下,说:多伟大我不知道,但是我知道很伟大。
这里,我想说一句可能有点片面的话,就是:如今这世界上,凡是带电的地方,可能都会有她(C语言)或者她的子孙的影子。
任何比C语言更低级的语言,都不足以完整地抽象一个计算机系统;任何比C高级的语言,都可以用C来实现。
1.2 C语言之父
Dennis Ritchie
Ritchie贝尔实验室的个人主页地址 https://www.bell-labs.com/usr/dmr/www/index.html丹尼斯·麦卡利斯泰尔·里奇(英语:Denni ...
redis事件驱动(aeEventLoop)原理分析
关于Redis事件驱动众所周知,Redis是高性能的、基于内存的、k-v数据库。其强大的功能背后,存在着2种不同类型的事件驱动,包括:
文件事件(File event)
时间事件(Time event)
文件事件是对相关的 fd 相关操作的封装,时间事件则是对定时任务相关操作的封装。Redis server通过文件事件来进行外部请求的处理与操作,通过时间事件来对系统内部产生的定时任务进行处理。(本文重点讲解文件事件相关的操作流程以及原理)
文中探讨的原理及源码基于Redis官方 v7.0 版本
Redis事件驱动的相关源码在Redis源码中,涉及事件驱动相关的源码文件主要有以下几个(以ae作为文件名称前缀):
1234567src├── ae.c ├── ae.h├── ae_epoll.c├── ae_evport.c├── ae_kqueue.c└── ae_select.c
ae.c文件事件驱动/时间事件驱动的核心处理逻辑
ae.h文件事件驱动/时间事件驱动结构体、方法签名的定义
ae_epoll.clinux os 文件事件驱动涉及的i ...
关于redis配置信息初始化
关于Redis配置信息Redis Server服务启动过程中,一般需要指定一个配置文件,官方默认配置文件为redis.conf,该文件用于指示Redis运行时状态、处理数据策略等方面。
使用配置文件/path/to/redis.conf来启动Redis Server服务,执行命令如下所示:
1./redis-server /path/to/redis.conf
如果在服务启动时,未指定配置文件,则Redis会使用默认的配置项。
Redis Server有一个全局变量static_configs,其存储着157个(v7.0版本)服务默认使用的通用配置项(默认配置可被自定义配置覆盖),如果包含一些其他特殊的配置,整个配置项可能会更多。
默认配置项信息,如下所示:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 ...
redisServer、redisDB与数据字典dict
关于Redis众所周知Redis是流行的、开源的,使用C语言开发的高性能,基于内存的key/value数据库。它具有高效、精心设计的底层数据结构,同时支持多种数据类型(string、list、set、zset、hash、bitmap、geo、hyperloglog等),让其能够拥有100K+/s的读写性能。正是由于这些优势让它在众多数据库中脱颖而出,支撑着众多互联网公司的海量业务。那么你有没有想过,它的底层是如何运作的?本文从RedisServer的底层结构入手,并通过追溯Set指令操作过程与key的过期时间窥探一下运行原理。
本文探讨的原理及源码均基于Redis官方 v7.0 版本
redisServer、redisDB与数据字典dictRedis服务是常见的c/s架构设计,即:Redis client客户端通过与Redis Server服务端建立连接后对存储在Redis Server端的数据进行操作。Redis Server作为一个单独的进程运行在计算机上,其对数据进行操作的工作线程为单线程,减少了锁开销以及上下文的切换。在Redis Server ...
Redis+DB实现基于号段的发号器原理
什么是发号器在互联网场景中,很多业务要求生成唯一的ID号,以用于区分某些资源。常见例子:电商系统中的订单ID号、聊天群组中的消息ID号、上传文件到存储系统中之后生成的文件ID号、用户注册系统中的用户ID号、商户系统中的商户ID号、开放平台中的开发者账号ID、餐饮店的排队进餐号、影剧院票据单号、医院/银行排队号等等,这些基本都是基于先来后到的规则生成,以期达到唯一性或稍显公平的享受某些资源。你是否想过使用技术应该如何实现呢? 下面引出本文主角:发号器(ticket dispenser),也可称之为ID生成器。
生成的ID号可以是字符串也可以是整数,本文仅探讨生成整数id的发号器实现原理
在互联网行业中,为了保证服务的稳定性、可用性、并发性等指标,服务一般是采用集群多节点部署,如何保证在这些不同的节点生成符合业务要求的ID,又引出另一个概念:分布式ID生成器(实现方案有多种)。关于分布式ID的常见实现方式参考笔者文章:分布式ID的5种生成方式以及Go源码中的一种应用,文章中列举了常见的5种实现方式以及原理。本文,则重点讲解使用Redis+DB基于号段的发号器实现原理。
实现发 ...
IoT设备影子功能介绍与实现
IoT平台架构在物联网领域,应用往往会通过调用集成并实现了MQTT协议的broker的平台与设备进行数据通信,已达到端、云互动与数据流转。常见的IoT架构图如下所示:
在IoT平台中为了达到控制设备实现的功能比较多,但是大致分为3类:
指令控制 (云端控制设备的动作与操作)
属性控制 (云端更新or获取设备拥有的属性)
事件控制 (设备触发某些事件上报给云端)
下面我们来聊聊属性控制中常用的功能-设备影子的实现原理,并通过一些细节来研究其交互过程。
设备影子作用设备影子数据模型是一个json格式数据,主要用于:存储设备当前上报的属性值和IoT平台期望下发给设备的属性值,且设备影子功能只存储最近一次的上报值和属性值。用户可通过应用或直接操作IoT平台API来查询或修改设备影子,以达到获取设备最新属性或将期望属性下发给设备的操作。
引用自:https://support.huaweicloud.com/intl/zh-cn/productdesc-IoT/iot_04_0006.html (下文中应用程序简称应用)
查询设备属性状态:应用直接向设备查询状态时,由于设备可能 ...
通过礼品卡购买美区AppleID付费App
前提说明首先,能够打开这篇文章,笔者默认你知道文章标题的含义。其次,要有一个美区AppleID。
那么,接下来一起看看怎么通过礼品卡购买Apple付费APP吧。
礼品卡购买步骤
注意: 演示操作中使用的邮箱 ivansli100#hotmail.com 为笔者的邮箱,一定要改成你们自己的。
[1] 登录苹果官网礼品卡页面,选择礼品卡发货方式https://www.apple.com/shop/buy-giftcard/giftcard
国内用户,选择邮箱即可
[2] 选择礼品卡卡面样式以及礼品卡金额(最低是10美元)
[3] 填写礼品卡收件人和发件人信息,包括名字和邮箱
发件人信息就可以随便,关键是收件人的邮箱,一定要能接收到苹果给你发送的邮件(最好是AppleID邮箱)。点击 Add to Bag 进入到 Check Out 页面。
[4] 检查信息没问题就 Check Out
[5] 选择登录账号购买 or 游客身份购买,都行
笔者这里选择方式2,游客身份购买。
[6] 付款方式需要一张外币(Vias、MasterCard)信用卡,国内很多银行都可以申请。
[7 ...
分布式ID的5种生成方式以及Go源码中的一种应用
关于分布式ID从目前互联网的系统架构来看,大部分公司为了避免服务节点出现单点故障、保持高可用、高性能等特性,在部署服务时都会部署多个节点,每个节点承担整个服务的一部分请求。对于同一服务多个节点中的每个节点来说,提供的功能相同。节点在处理数据的过程中会根据不同的业务场景,操作相同或不同的数据源。
对于操作相同的数据源,则会形成数据竞争(大部分情况下需要加锁、串行执行)。对于操作不同的数据源,则可以并行/并发处理(无需加锁)。
对于某些场景下的数据资源,需要有全局唯一的数据资源标识。例如:电商系统中的订单ID号、聊天群组中的消息ID号、上传文件到存储系统中之后生成的文件ID号、用户注册系统中的用户ID号、商户系统中的商户ID号、开放平台中的开发者账号ID等等场景。
这些ID号在分布式系统架构中,可以统称为分布式ID。
常见的5种分布式ID生成方式按照是否需要协调(co-ordination)节点,生成分布式ID的方法可以分为2大类:
不需要联网,单服务节点可以在本地生成
需要联网,依赖协调节点生成
这2大类中又可以细分出来多种具体的实现方式,汇总如下图所示:
图片来自:bl ...
Protobuf Name Conflict 分析与解决
问题背景最近,在对老项目进行重构工作。在重构过程中发现需要通过 grpc 调用若干远端微服务,远端微服务都有提前定义好的 proto,在运行时(编译通过,运行则panic)出现了 name conflict 冲突问题。也就是说,在运行时报错提示存在相同名称的 message 消息体。
具体报错信息,如下所示:
1234567891011121314151617181920212223242526➜ app > go mod tidy ➜ app > go build main.go ➜ app > ./main api startpanic: proto: file "usermgt.proto" has a name conflict over pb.Response previously from: "eslServer/pkg/microgrpc/merchant/pb" currently from: "eslServer/pkg/microgrpc/usermgt ...