酸梅猫的博客

  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

REST VS RPC

发表于 2020-09-10 | 更新于 2020-09-11 | 分类于 网络

网上很多关于REST和RPC的区别讨论,但是大多都关注于他们格式,例如:
RPC: POST /createUser vs REST: POST /user

其实他们的核心不同是如何discovery peers, performance和代码风格

Discovery Peers & Performance

通常,RPC使用在一个系统内部的不同微服务。 一般来说需要一个注册服务或者平台来让消费者发现生产者。当他们交流的时候可以直接host to host连接。再加上RPC可以拥有自己定制的交流协议,这样可以大大的降低使用RPC的延迟。

REST 一般大量用于对外部的Public API。 需要在服务器前面架设一个网关和负载均衡。这样可以方便的暴露一个单独的网址,但是会增加延迟。使用REST可以更方便的对GET请求进行Cache。例如CDN Cache。

代码风格

使用PRC使得不同的微服务之间更加耦合,由于很容易添加一个新的RPC方法,经常会导致RPC服务臃肿。大多情况下使用同一种语言和框架。

REST 更加注重的自己的Schema,ACTION + Resource,使得API设计更加稳定。而且编程语言和框架也没有特殊要求。

阻断与非阻断I/O

发表于 2020-08-11 | 更新于 2020-09-11 | 分类于 工作原理

I/O 基础

简单介绍一下I/O的基本工作方式

  1. 你的程序通过“syscall()”请求操作系统的内核去做一个I/O操作。
  2. 一个”syscall()”是阻断的,你的程序需要等待内核返回才能继续执行你的代码。
  3. 内核执行底层的I/O操作,大多在硬件层面,执行时间根据的硬件的速度而变化。
阅读全文 »

进程,线程和协程

发表于 2020-08-11 | 更新于 2020-09-11 | 分类于 工作原理

进程(process)

进程拥有独立的内存,寻址空间和寄存器。进程是直接被内核(kernel)管理的,一般每一个程序都拥有自己的线程。他们相互独立确保不会干扰彼此的工作。

在一个多进程的计算机中,一个CPU需要同时运行多个进。这是通过中断当前进程,然后保存当前进程中的内存,寄存器,PC(program counter), 变量表等,然后让下一个进程来运行,我们称之为上下文切换(context switch)。上下文切换是相对消耗运算量的,尤其是有很多进程并发的时候,频繁的上下文切换将会占用大量的CPU资源。

线程(thread)

线程是一种轻量级进程,线程直接可以共享内存,但执行不同的代码,所以各自有自己的栈内存和寄存器等。

线程一般由应用软件来创建,线程之间的上下文切换也是类似于进程,唯一的区别是会保留虚拟内存。

协程(coroutine/goroutine)

进程和线程都是内核(kernel)级别的中断和上下文切换。他们都有在大量多线程/进程的情况中消耗CPU资源的问题。

协程将内核级别的上下文切换转换到了应用程序内。这样做的好处的通过应用程序的协调,避免的大量的内核上下文切换。而且很多协程中都使用自愿退出的模式,避免的大量的需要上下文切换的情况。

例如:RxJava, Kotlin coroutines, Go(goroutines)

更多阅读:
Cooperative vs. Preemptive: a quest to maximize concurrency power

Elastic Search 搜索

发表于 2020-05-09 | 更新于 2020-09-11 | 分类于 学习笔记

如何搜索

这里我们会尽量用java作为例子来解释如何使用ElasticSearch。ES HighLevel REST Client

BoolQuery 的用法与特性

BoolQuery 作为一个主要的Query结构一般用于整个Query的根。Query的结果会根据score默认排序

1
2
searchSourceBuilder.query(QueryBuilders.boolQueryBuilder()); 
searchRequest.source(searchSourceBuilder);

BoolQuery 拥有4个不同的Query类型。

1
2
3
4
5
6
7
8
9
10
11
12
// 必须匹配,匹配会增加score。MatchQuery 这里表示"名字"必须包含“大卫”或者“David”其中一个, 多个匹配会增加其结果的score。
boolQueryBuilder.must(QueryBuilders.matchQuery("名字", "大卫 David"))
// 每一个query类型都可以添加多个子Query,其关系是“AND”。并且可以是BoolQuery
boolQueryBuilder.must(QueryBuilders.boolQuery())
// 必须匹配,匹配不影响score。TermsQuery 这里表示"id"必须等于“123”或者“321”
boolQueryBuilder.filter(QueryBuilders.termsQuery("id", "123", "321"))
// 非必须匹配,匹配增加score。
boolQueryBuilder.should()
// 设定最少匹配“should”的数量,如果没有规定“must”/“filter”默认值是1,有的话默认值是0
boolQueryBuilder.minimalShouldMatch(1)
// 必须不包含,不影响score。
boolQueryBuilder.must_not()

阅读全文 »

测试的设计 - Clean Architecture Part 11

发表于 2019-04-06 | 更新于 2020-09-11 | 分类于 读书 , Clean Architecture

把测试当作系统模块

大多人在设计系统的时候经常犯一个错误,没有把测试作为一个模块设计到系统中。

未经设计的测试会使系统变得难以改变。经常一个很小大改动,或者重构,就会使得很多测试失败。

优良的测试不会使得系统的开发和进化受到限制。它会作为系统的一个独立的模块而存在。它也应该具有模块的界限,解耦和依赖倒置。

测试API

实现以上方案的一个技巧是,给测试模块提供专用的API。

  • 减少测试时的各种配置的设置,例如提供一个不需要登陆的API,提供一个不使用云数据库的API。这样测试可以与这些配置解耦,更容易去测试核心逻辑。

  • 减少结构上的耦合。很多情况下,大家写测试都是一一对应的。例如在写单元测试的时候,将系统的类和方法与测试中的类与方法一一对应。这样的测试具有极强的耦合,导致难以修改和扩展。但是当我们应用测试API时,将一组类或方法所提供的功能,总结为一个API。这样,测试就和系统解耦了。测试只关心功能的正确性,而不关心实现的细节。

难测对象模式 - Clean Architecture Part 10

发表于 2019-04-04 | 更新于 2020-09-11 | 分类于 读书 , Clean Architecture

展示者和难测对象模式(Presenters and Humble Objects)

将系统中难以测试的部分取出来,而使得其他逻辑易于测试。

例如说,UI就是难以测试的部分,而展示者(Presenters)则把系统中心的数据转化为UI可以直接用来现实的格式。这样我们就可以通过测试展示者来测试系统的行为。

1
Application –> Presenter –> ViewModel –> View

Data Access Object(DAO)

DAO是一个包含所有业务逻辑所需数据读写方法的接口。这个接口将被用例使用,而由数据库的模块implement。

服务Proxy

当你的系统需要使用其他网络服务的时候,最好的方法是创建一个Proxy的类来隔离耦合。这个Proxy的类会将系统提供的数据转化为其他网络服务接受的数据格式。这样我们就可以直接mock这个Proxy的类来进行测试了。

部分隔离

在很多情况下严格执行界限分离的构架非常的昂贵。

  • 严格的界限分离需要多写很多代码
  • 需要额外的工作去部署
  • 你有可能并不需要分离这部分的模块
  • 你可以使用部分隔离的方法,按照界限分离的方式开发,但是只放在同一个模块中。
  • Strategy Pattern
  • Facade Pattern

入口程序模块(The Main Component)

  • 入口程序依赖于所有的部分,它知道所有模块的存在。
  • 最细节的模块,需要创建所有的工厂类,模块等。
  • 为高级系统加载所有内容,然后将控制权交给它。
  • 当你把入口程序作为整个构架之外的插件来看待的话,系统配置的问题就会容易解决。

干净的构架 - Clean Architecture Part 9

发表于 2019-04-03 | 更新于 2020-09-11 | 分类于 读书 , Clean Architecture

这篇我们将介绍这本书最核心的概念 - 干净构架。

首先一个干净的构架应该拥有以下几点特征:

  • 不依赖于任何框架,数据库,UI,服务器
  • 在没有UI,数据库,服务器的情况下可以测试

阅读全文 »

实体与用例 - Clean Architecture Part 8

发表于 2019-04-01 | 更新于 2020-09-11 | 分类于 读书 , Clean Architecture
  • 规则指的就是一个软件的业务逻辑,也是它的价值所在。

  • 等级我们可以理解为模块到输入和输出的距离,距离越远模块等级越高。

  • 业务逻辑,就是可以使一个业务赚钱或者省钱的逻辑。

    阅读全文 »

界限:插件构架 - Clean Architecture Part 7

发表于 2019-03-31 | 更新于 2020-09-11 | 分类于 读书 , Clean Architecture

构架的关键是解耦,尤其是对一些“重要”决定的解耦。在软件开发初期,经常会有一些看似很重要但是与业务逻辑其实没有关系的决定,例如框架,数据库,服务器等。一个优秀的系统是不会依赖于这些决定的。

我们要对这些于业务逻辑无关的“重要”决定划清界限。

例如:


阅读全文 »

解耦 - Clean Architecture Part 6

发表于 2019-03-31 | 更新于 2020-09-11 | 分类于 读书 , Clean Architecture

其实很多人都知道软件构架和开发过程中的核心思想就是解耦。解耦的核心就是将需要以不同的原因而修改的部分分开。

水平解耦

将用户界面,数据库,业务逻辑,服务框架等元素解耦,因为不同层次的结构所改变的原因并不一致。例如,用户界面的修改不应该导致数据库的修改,同样,数据库的修改也不应该影响用户界面。

阅读全文 »

12

酸梅猫

一只西雅图的程序员
17 日志
9 分类
13 标签
© 2019 – 2020 酸梅猫
由 Hexo 强力驱动
|
主题 – NexT.Mist