Clay 的技术空间

用进废退 | 艺不压身

Snap 介绍

Snap 是 Ubuntu 母公司 Canonical 于 2016 年 4 月发布 Ubuntu-16.04 时引入的一种全新的、安全的、易于管理的、沙盒化的软件包管理方式,与传统的 dpkg/apt 有着很大的区别,背后主要的动机是解决 Linux 平台的碎片化问题。Snap 的安装包扩展名是 .snap,类似于一个容器,它包含一个应用程序需要用到的所有文件和库(Snap 包里包含一个私有的 root 文件系统,里面包含了依赖的软件包)。不管底层系统如何,Snap 都可轻松安装、升级、降级和移除应用,因此 Snap 的应用程序很容易安装在任何基于 Linux 的系统上,而且支持用户在同一个系统中安装同一应用程序的多个版本。使用 Snap 包的好处就是它解决了应用程序之间的依赖问题,使应用程序之间更容易管理,但是由此带来的问题就是占用更多的磁盘空间。类似的应用程序容器技术还有大名鼎鼎的 FlatpakAppImage。Snap 适用于 CentOS 7.6+ 和 Red Hat Enterprise Linux 7.6+,它很好地弥补了 Centos 桌面软件资源不多的缺点,可以从 Extra Packages for Enterprise Linux(EPEL)存储库安装。Snap 的工作原理如下图所示:

snap-framework

阅读全文 »

概述

读写分离要做的事情就是决定一条 SQL 该到哪个数据库去执行,至于谁来做决定数据库这件事,要么数据库中间件去做,要么应用程序自己去做。首先针对应用程序自己去做的场景,读写分离的职责应该属于数据访问层而不是业务层,其次读写分离不应该入侵到代码中。因此在 Service—DAO—ORM— 数据库驱动的调用链中,要想做到代码弱入侵性或者零入侵性,只能将读写分离写在 ORM 层或者数据库驱动层,写在 ORM 层就和具体 ORM 框架耦合,写在数据库驱动层,就和具体数据库耦合。至于在 ORM 层还是在数据库驱动层实现读写分离,主要看更换 ORM 框架和数据库哪个成本更高和实现的难易程度。一般来讲,读写分离的核心方案主要有以下几种:

  • 第一种构建多套环境,优势是方便控制也容易集成一些简单的分布式事务,缺点是非动态同时代码量较多,配置难度大;
  • 第二种是依靠数据库中间件(例如:MyCat),由中间件做读写分离,优势是对整个应用程序都是透明的,缺点是降低性能,不支持多数据源事务;
  • 第三种是应用程序自己去做,例如使用支持读写分离的数据库驱动、使用 Spring 原生提供的 AbstractRoutingDataSource。后者需要控制只读事务和读写事务切换到主库,写操作切换到主库,读操作切换到从库;同时保证单个事务里面所有的 SQL 都是在同一个数据源里执行。缺点是多数据源的配置不灵活,不支持多数据源事务。具体实现方式可参考 基于 Service 层的 Spring 路由数据源 + AOP / Annotation基于 ORM 层的 Spring 路由数据源 + Mybatis 插件 / Annotation
阅读全文 »

大纲

相关资源

缓存介绍

主流缓存框架

Ehcache、Caffeine 、Spring Cache、Guava Cache、JetCache、Hazelcast、Infinispan

主流缓存解决方案

  • 内存缓存(如 Ehcache、Caffeine) — 速度快,进程内可用
  • 集中式缓存(如 Redis、Memcached)— 可同时为多节点提供服务
阅读全文 »

大纲

IDEA 介绍

JetBrains 是一家捷克的软件开发公司,IntelliJ IDEA 是该公司旗下赫赫有名的 IDE 产品,支持目前主流的技术和框架,擅长企业应用、移动应用和 Web 应用的开发。IntelliJ IDEA 目前有两个版本,分别是社区版(免费)与旗舰版(收费),社区版支持 JavaSE、Android、Kotlin、Groovy、Scala 开发,旗舰版额外支持 JavaEE 开发。IntelliJ IDEA 和 Eclipse 一样有强大的插件系统支持,官方的插件可以从这里获取。

IDEA 的 config 与 system 目录

启动 IntelliJ IDEA 后会自动生成一个全新的默认配置,配置目录的位置分别是 /.IntelliJIdea2019.1/config、/.IntelliJIdea2019.1/system。其中 config 目录是 IntelliJ IDEA 个性化的配置目录,或者说是整个 IDE 的设置目录,该目录主要记录了 IDE 主要配置功能、插件功能、自定义的代码模板、自定义的文件模板、自定义的快捷键、Project 的 tasks 记录等等个性化设置。system 目录是 IntelliJ IDEA 的系统文件目录,是 IntelliJ IDEA 与开发项目的一个桥梁,里面主要有缓存、索引、容器文件输出等等,虽然不是最重要目录,但也是最不可或缺的目录之一。

1
2
3
4
5
# Linux下重置IDEA的所有配置
$ rm -rf ~/.config/JetBrains
$ rm -rf ~/.local/share/JetBrains
$ rm -rf ~/.IntelliJIdea2019.1/config
$ rm -rf ~/.IntelliJIdea2019.1/system
阅读全文 »

SpringBoot 整合 gRPC

gRPC 的四种服务类型定义

  • 一个简单 RPC,客户端使用存根发送请求到服务器并等待响应返回,就像平常的函数调用一样。

    1
    rpc GetFeature(Point) returns (Feature) {}
  • 一个服务器端流式 RPC,客户端发送请求到服务器,拿到一个流去读取返回的消息序列。客户端读取返回的流,直到里面没有任何消息。通过在响应类型前插入 stream 关键字,可以指定一个服务器端的流方法。

    1
    rpc ListFeatures(Rectangle) returns (stream Feature) {}
  • 一个 客户端流式 RPC,客户端写入一个消息序列并将其发送到服务器,同样也是使用流。一旦客户端完成写入消息,它等待服务器完成读取返回它的响应。通过在请求类型前指定 stream 关键字来指定一个客户端的流方法。

    1
    rpc RecordRoute(stream Point) returns (RouteSummary) {}
  • 一个双向流式 RPC 是双方使用读写流去发送一个消息序列。两个流独立操作,因此客户端和服务器可以以任意喜欢的顺序读写:比如,服务器可以在写入响应前等待接收所有的客户端消息,或者可以交替地读取和写入消息,或者其他读写的组合,每个流中的消息顺序都会被预留。通过在请求和响应前加 stream 关键字去制定方法的类型。

    1
    rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
    阅读全文 »

前言

本文将介绍 gRPC、Protocol Buffers 的概念,同时会给出 Protocol Buffers 代码生成器的使用教程,还有编写第一个基于 gRPC 的服务提供者与服务消费者的示例程序。

相关站点

gRPC 简介

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java、Go 语言版本,分别是:grpc、grpc-java、grpc-go,其中 C 版本支持 C、C++、Node.js、Python、Ruby、Objective-C、PHP、C#。gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特性。在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。值得说明的是,gRPC 客户端和服务端可以在多种环境中运行和交互,支持用任何 gRPC 支持的语言来编写,所以可以很容易地用 Java 创建一个 gRPC 服务端,用 Go、Python、Ruby 来创建客户端。

阅读全文 »

前言

集群模式

RabbitMQ 是用 Erang 开发的,集群模式分为两种普通模式镜像模式,可以说镜像模式普通模式的升级版,其中 RabbitMQ 默认使用的是 普通模式

  • 普通模式:
    以两个节点(rabbit01、rabbit02)为例来进行说明,rabbit01 和 rabbit02 两个节点仅有相同的元数据,即队列的结构,但消息实体只存在于其中一个节点 rabbit01(或者 rabbit02)中。当消息进入 rabbit01 节点的 Queue 后,consumer 从 rabbit02 节点消费时,RabbitMQ 会临时在 rabbit01、rabbit02 间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer。所以 consumer 应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理 Queue。否则无论 consumer 连 rabbit01 或 rabbit02,出口总在 rabbit01,会产生瓶颈。当 rabbit01 节点故障后,rabbit02 节点无法取到 rabbit01 节点中还未消费的消息实体。如果做了消息持久化,那么得等 rabbit01 节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。

  • 镜像模式:
    在普通模式的基础上,把需要的队列做成镜像队列,存在于多个节点,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取,也就是说多少节点消息就会备份多少份。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉,所以在对业务可靠性要求较高的场合中适用。由于镜像队列之间消息自动同步,且内部有选举 Master 机制,即使 Master 节点宕机也不会影响整个集群的使用,达到去中心化的目的,从而有效的防止消息丢失及服务不可用等问题

集群节点的区别

RabbitMQ 的集群节点分为磁盘节点、内存节点。RabbitMQ 支持消息的持久化,也就是数据写在磁盘上。在 RabbitMQ 集群中,必须至少有一个磁盘节点,否则队列元数据无法写入到集群中。当磁盘节点宕掉时,集群将无法写入新的队列元数据信息。如果 RabbitMQ 集群全部宕机,必须先启动磁盘节点,然后再启动内存节点。最合适的方案就是既有磁盘节点,又有内存节点,推荐 1 个 磁盘节点 + 2 个内存节点的集群搭建方式。

阅读全文 »

RabbitMQ 的非阻塞 I/O

NIO 通常也称非阻塞 I/O,包含三大核心部分:Channel(信道)、Buffer(缓冲区)和 Selector(选择器)。NIO 是基于 Channel 和 Buffer 进行操作的,数据总是从信道读取数据到缓冲区中,或者从缓冲区写入到信道中,而 Selector 则用于监听多个信道的时间(比如连接打开,数据到达等)。因此,单线程可以监听多个数据的信道。由于 RabbitMQ 采用类似 NIO(Non-blocking I/O)的做法,选择 TCP 连接复用,不仅可以减少性能开销,同时也便于管理。每个线程把持一个信道,所以信道复用了 Connection 的 TCP 连接。同时 RabbitMQ 可以确保每个线程的私密性,就像拥有独立的连接一样。当每个信道的流量不是很大时,复用单一的 Connection 可以在产生性能瓶颈的情况下有效地节省 TCP 连接资源。但是信道本身的流量很大时,这时候多个信道复用一个 Connection 就会产生性能瓶颈,进而使整体的流量被限制了。此时就需要开辟多个 Connection,将这些信道均摊到这些 Connection 中,至于这些相关的调优策略需要根据业务自身的实际情况进行调节。

RabbitMQ 的 ConnectionFactory、Connection、Channel

ConnectionFactory、Connection、Channel 都是 RabbitMQ 对外提供的 API 中最基本的对象。Connection 是 RabbitMQ 的 Socket 连接,它封装了 Socket 协议相关部分逻辑。ConnectionFactory 是客户端与 Broker 的 TCP 连接工厂,负责根据 URI 创建 Connection。Channel 是与 RabbitMQ 打交道的最重要的一个接口,大部分的业务操作是在 Channel 这个接口中完成的,包括定义 Queue、定义 Exchange、绑定 Queue、绑定 Exchange、发布消息等。如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 Connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个 Thread 创建单独的 Channel 进行通讯,AMQP Method 包含了 Channel ID 帮助客户端和 Message Broker 识别 Channel,所以 Channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP Connection 的开销。

阅读全文 »

相关站点

RabbitMQ 基础概念

AMQP(Advanced Message Queuing Protocol)高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP 的主要特征是面向消息、队列、路由(包括点对点和发布 / 订阅)、可靠性、安全。RabbitMQ 是一个开源的 AMQP 标准实现,服务器端用 Erlang 语言编写,支持多种客户端,如:Python、Ruby、C#、Java、PHP、GO、JavaScript 等。RabbitMQ 用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等方面表现不俗。

RabbitMQ 的用户角色分类

  • 超级管理员 (administrator),可登陆管理控制台,可查看所有的信息,并且可以对用户,策略 (policy) 进行操作
  • 监控者 (monitoring),可登陆管理控制台,同时可以查看 rabbitmq 节点的相关信息 (进程数,内存使用情况,磁盘使用情况等)
  • 策略制定者 (policymaker),可登陆管理控制台,同时可以对 policy 进行管理。但无法查看节点的相关信息,与 administrator 的对比,administrator 能看到节点信息
  • 普通管理者 (management),仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理
  • 其他,无法登陆管理控制台,通常就是普通的生产者和消费者
阅读全文 »
0%