go操作MySQL
- 使用第三方开源的mysql库: github.com/go-sql-driver/mysql (mysql驱动)
- github.com/jmoiron/sqlx (基于mysql驱动的封装)
命令行输入 :
- go get github.com/go-sql-driver/mysql
- go get github.com/jmoiron/sqlx
Insert操作
Select操作
Update操作
Delete操作
MySQL事务
go操作Redis
使用第三方开源的redis库: github.com/garyburd/redigo/redis: go get github.com/garyburd/redigo/redis
Redis连接
String类型Set、Get操作
String批量操作
设置过期时间
List队列操作
Hash表
Redis连接池
go操作ETCD
etcd是使用Go语言开发的一个开源的、高可用的分布式key-value存储系统,可以用于配置共享和服务的注册和发现。
类似项目有zookeeper和consul。
etcd具有以下特点:
- 完全复制:集群中的每个节点都可以使用完整的存档
- 高可用性:Etcd可用于避免硬件的单点故障或网络问题
- 一致性:每次读取都会返回跨多主机的最新写入
- 简单:包括一个定义良好、面向用户的API(gRPC)
- 安全:实现了带有可选的客户端证书身份验证的自动化TLS
- 快速:每秒10000次写入的基准速度
- 可靠:使用Raft算法实现了强一致、高可用的服务存储目录
etcd应用场景
服务发现
服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp 或 tcp 端口,并且通过名字就可以查找和连接。
配置中心
将一些配置信息放到 etcd 上进行集中管理。
这类场景的使用方式通常是这样:应用在启动的时候主动从 etcd 获取一次配置信息,同时,在 etcd 节点上注册一个 Watcher 并等待,以后每次配置有更新的时候,etcd 都会实时通知订阅者,以此达到获取最新配置信息的目的。
分布式锁
因为 etcd 使用 Raft 算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。
- 保持独占即所有获取锁的用户最终只有一个可以得到。etcd 为此提供了一套实现分布式锁原子操作 CAS(CompareAndSwap)的 API。通过设置prevExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功。而创建成功的用户就可以认为是获得了锁。
- 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd 为此也提供了一套 API(自动创建有序键),对一个目录建值时指定为POST动作,这样 etcd 会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用 API 按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。
为什么用 etcd 而不用ZooKeeper?
etcd 实现的这些功能,ZooKeeper都能实现。那么为什么要用 etcd 而非直接使用ZooKeeper呢?
为什么不选择ZooKeeper?
部署维护复杂,其使用的Paxos强一致性算法复杂难懂。官方只提供了Java和C两种语言的接口。
使用Java编写引入大量的依赖。运维人员维护起来比较麻烦。
最近几年发展缓慢,不如etcd和consul等后起之秀。
为什么选择etcd?
- 简单。使用 Go 语言编写部署简单;支持HTTP/JSON API,使用简单;使用 Raft 算法保证强一致性让用户易于理解。
- etcd 默认数据一更新就进行持久化。
- etcd 支持 SSL 客户端安全认证。
最后,etcd 作为一个年轻的项目,正在高速迭代和开发中,这既是一个优点,也是一个缺点。优点是它的未来具有无限的可能性,缺点是无法得到大项目长时间使用的检验。然而,目前 CoreOS、Kubernetes和CloudFoundry等知名项目均在生产环境中使用了etcd,所以总的来说,etcd值得你去尝试。
etcd集群
etcd 作为一个高可用键值存储系统,天生就是为集群化而设计的。由于 Raft 算法在做决策时需要多数节点的投票,所以 etcd 一般部署集群推荐奇数个节点,推荐的数量为 3、5 或者 7 个节点构成一个集群。
操作ETCD
put和get操作
watch操作
lease租约
keepAlive
基于etcd实现分布式锁
zookeeper
简单的分布式server
目前分布式系统已经很流行了,一些开源框架也被广泛应用,如dubbo、Motan等。对于一个分布式服务,最基本的一项功能就是服务的注册和发现,而利用zk的EPHEMERAL节点则可以很方便的实现该功能。EPHEMERAL节点正如其名,是临时性的,其生命周期是和客户端会话绑定的,当会话连接断开时,节点也会被删除。下边我们就来实现一个简单的分布式server:
server:
服务启动时,创建zk连接,并在go_servers节点下创建一个新节点,节点名为”ip:port”,完成服务注册
服务结束时,由于连接断开,创建的节点会被删除,这样client就不会连到该节点
client:
先从zk获取go_servers节点下所有子节点,这样就拿到了所有注册的server
从server列表中选中一个节点(这里只是随机选取,实际服务一般会提供多种策略),创建连接进行通信
这里为了演示,我们每次client连接server,获取server发送的时间后就断开。主要代码如下:
go操作kafka
Kafka介绍
- kafka使用scala开发,支持多语言客户端(c++、java、python、go等)
- Kafka最先由LinkedIn公司开发,之后成为Apache的顶级项目。
- Kafka是一个分布式的、分区化、可复制提交的日志服务
- LinkedIn使用Kafka实现了公司不同应用程序之间的松耦和,那么作为一个可扩展、高可靠的消息系统
- 支持高Throughput的应用
- scale out:无需停机即可扩展机器
- 持久化:通过将数据持久化到硬盘以及replication防止数据丢失
- 支持online和offline的场景
Kafka的特点
Kafka是分布式的,其所有的构件borker(服务端集群)、producer(消息生产)、consumer(消息消费者)都可以是分布式的。
在消息的生产时可以使用一个标识topic来区分,且可以进行分区;每一个分区都是一个顺序的、不可变的消息队列, 并且可以持续的添加。
同时为发布和订阅提供高吞吐量。据了解,Kafka每秒可以生产约25万消息(50 MB),每秒处理55万消息(110 MB)。
消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡
常用的场景
**监控:**主机通过Kafka发送与系统和应用程序健康相关的指标,然后这些信息会被收集和处理从而创建监控仪表盘并发送警告。
消息队列: 应用程度使用Kafka作为传统的消息系统实现标准的队列和消息的发布—订阅,例如搜索和内容提要(Content Feed)。比起大多数的消息系统来说,Kafka有更好的吞吐量,内置的分区,冗余及容错性,这让Kafka成为了一个很好的大规模消息处理应用的解决方案。消息系统 一般吞吐量相对较低,但是需要更小的端到端延时,并尝尝依赖于Kafka提供的强大的持久性保障。在这个领域,Kafka足以媲美传统消息系统,如ActiveMR或RabbitMQ
站点的用户活动追踪: 为了更好地理解用户行为,改善用户体验,将用户查看了哪个页面、点击了哪些内容等信息发送到每个数据中心的Kafka集群上,并通过Hadoop进行分析、生成日常报告。
流处理: 保存收集流数据,以提供之后对接的Storm或其他流式计算框架进行处理。很多用户会将那些从原始topic来的数据进行 阶段性处理,汇总,扩充或者以其他的方式转换到新的topic下再继续后面的处理。例如一个文章推荐的处理流程,可能是先从RSS数据源中抓取文章的内 容,然后将其丢入一个叫做“文章”的topic中;后续操作可能是需要对这个内容进行清理,比如回复正常数据或者删除重复数据,最后再将内容匹配的结果返 还给用户。这就在一个独立的topic之外,产生了一系列的实时数据处理的流程。
日志聚合:使用Kafka代替日志聚合(log aggregation)。日志聚合一般来说是从服务器上收集日志文件,然后放到一个集中的位置(文件服务器或HDFS)进行处理。然而Kafka忽略掉 文件的细节,将其更清晰地抽象成一个个日志或事件的消息流。这就让Kafka处理过程延迟更低,更容易支持多数据源和分布式数据处理。比起以日志为中心的 系统比如Scribe或者Flume来说,Kafka提供同样高效的性能和因为复制导致的更高的耐用性保证,以及更低的端到端延迟
持久性日志: Kafka可以为一种外部的持久性日志的分布式系统提供服务。这种日志可以在节点间备份数据,并为故障节点数据回复提供一种重新同步的机制。Kafka中日志压缩功能为这种用法提供了条件。在这种用法中,Kafka类似于Apache BookKeeper项目。
Kafka中包含以下基础概念
- Topic(话题):Kafka中用于区分不同类别信息的类别名称。由producer指定
- Producer(生产者):将消息发布到Kafka特定的Topic的对象(过程)
- Consumers(消费者):订阅并处理特定的Topic中的消息的对象(过程)
- Broker(Kafka服务集群):已发布的消息保存在一组服务器中,称之为Kafka集群。集群中的每一个服务器都是一个代理(Broker). 消费者可以订阅一个或多个话题,并从Broker拉数据,从而消费这些已发布的消息。
- Partition(分区):Topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)
Message:消息,是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息。
go操作RabbitMQ
环境准备
安装Go
访问 Go官网 下载并安装最新版本的Go。
安装RabbitMQ
访问 RabbitMQ官网 安装RabbitMQ。安装完成后启动服务,并确保可以在浏览器中通过 http://localhost:15672 访问管理界面。
安装RabbitMQ客户端库
打开终端或命令提示符,运行以下命令来安装Go语言的RabbitMQ客户端库:
基础概念
- AMQP: Advanced Message Queuing Protocol,一种为应用程序之间提供通用协议的标准。
- Exchange: 交换器,用来接收生产者发送的消息然后根据key决定如何路由消息。
- Queue: 消息队列,用来保存消息直到消费者获取它们。
- Binding: 绑定,用于将队列与交换器连接起来。
- Consumer: 消费者,接收消息的应用程序。
- Producer: 生产者,发送消息的应用程序。
基本示例
发送消息
接收消息
持久化消息
持久化队列
设置队列为持久化队列,即使RabbitMQ重启后队列仍然存在。
示例代码:
持久化消息
发布消息时设置Delivery.Persistent
为true。
示例代码:
发布确认
开启发布确认
在通道上启用发布确认功能。
示例代码:
等待确认
发布消息后等待确认结果。
示例代码:
事务
开启事务
开启事务后,可以确保消息处理的原子性。
示例代码:
RPC模式
实现RPC模式
通过队列传递请求和响应,实现远程过程调用。
示例代码:
Fanout Exchange
Fanout Exchange可以将消息广播到所有绑定的队列。
创建Fanout Exchange
示例代码:
绑定队列到Fanout Exchange
示例代码:
发布消息到Fanout Exchange
示例代码:
go操作ElasticSearch
连接Elasticsearch
创建客户端
使用elasticsearch.NewDefaultClient
创建客户端。
示例代码:
创建索引
使用esapi.PutMappingRequest
创建索引。
示例代码:
映射定义
使用esapi.PutMappingRequest
定义映射。
示例代码:
插入文档
使用esapi.IndexRequest
插入文档。
示例代码:
查询文档
使用esapi.SearchRequest
进行简单查询。
示例代码:
批量操作
批量插入
使用esapi.BulkRequest
进行批量插入。
示例代码:
更新文档
使用esapi.UpdateRequest
更新文档。
示例代码:
删除文档
使用esapi.DeleteRequest
删除文档。
示例代码:
聚合查询
使用esapi.SearchRequest
进行聚合查询。
示例代码:
复合查询
使用esapi.SearchRequest
进行复合查询。
示例代码:
排序查询
使用esapi.SearchRequest
进行排序查询。
示例代码:
NSQ
安装NSQ客户端
首先确保已经安装了Go环境,并且可以通过go version命令验证Go是否正确安装。
接着,安装Go语言的NSQ客户端库go-nsq:
NSQ生产者
生产者负责向NSQ集群发送消息。下面是一个简单的Go程序示例,展示如何使用go-nsq库来创建一个NSQ生产者:
在这个例子中,我们创建了一个NSQ生产者,并向名为test_topic的主题发送了一条消息。
NSQ消费者
消费者负责接收来自NSQ集群的消息。下面是一个简单的Go程序示例,展示如何使用go-nsq库来创建一个NSQ消费者:
在这个例子中,我们创建了一个NSQ消费者,并订阅了名为test_topic的主题。当接收到消息时,消费者会打印出消息的内容, https://t.me/gtokentool 。