2020-07-30 18:08,约7679字,阅读约16分钟记录一下笔者关于软件设计的一些相关认知。在开始之前,先引入两个概念目标和途径(这里可能会有些咬文嚼字,不过主要是为了区分主观和客观的一些细微差异)。
1 目标和途径 我们在做某一件事情的时候,总是会带有一定的目的性的:比如说一日三餐,是为了给身体补充所需的能量。那么这三餐具体如何落实呢,则会有多种多样的方式。比如你可以选择吃碳水食物、蔬菜、肉类、牛奶或者蛋类等等;也可以选择通过静脉注射一些所需的葡萄糖或者蛋白质。总之,能够为身体补充能量就可以了。
1.1 目标 那么在上述的小例子中,我们的目的就是给身体补 ...2018-03-31 09:02,约4980字,阅读约10分钟根据REST APIs的成熟度模型 ,此规范关注的是Level 2的APIs。
1 设计指南 HTTP APIs主要由四部分组成 : #HTTP, #URL, 资源,资源的表述。
资源的表述通常都采用#JSON格式,故而下文使用#JSON代指资源的表述。
根据这些组成部分,按照以下3个步骤设计APIs。
1.1 基于资源设计API 设计HTTP APIs的首要任务是识别出业务领域中的资源。资源是对服务端提供的服务进行分解、组合后的一个被命名的抽象概念。
有很重要一点需要明确 : 资源≠数据表,它们两个之间 ...2017-10-15 15:44,约8728字,阅读约18分钟衔接上文[理解REST] 04 基于网络应用的架构风格,上文总结了一些适用于基于网络应用的架构风格,以及其评估结果。在前文的基础上,本文介绍一下Web架构的需求,以及在对Web的关键协议进行设计和改进的过程中遇到的问题;以及在对基于网络应用的架构风格进行评估的过程中的领悟;结合Web的需求进而推导出REST这种架构风格,随后使用REST来指导Web架构的设计和改进工作。
1 Web的需求 在本系列博客的第一篇博客[理解REST] 01 REST的起源中,Web之父Berners-Lee在世界上第一个网站写 ...2017-05-30 09:18,约6762字,阅读约14分钟1 什么是OIDC? 看一下官方的介绍(http://openid.net/connect/) :
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, a ...2022-09-03 10:01,约928字,阅读约2分钟1 RowKey 在HBase中,RowKey的设计是否合理很大程度上会严重影响DB的读写性能是否均衡。原因在于HBase的数据分片完全是依赖RowKey的字典序来分割Region的;如果新增部分的数据无法均匀的散列在所有的Region中,就会造成只有部分Region的读写量非常之大,而其余的部分则在旁边打酱油。
推荐采用稳定性Hash算法(比如MD5)作为前缀,比如
String rawRowKey = userId; String prefix = md5(userId).hex().subStr( ...2022-05-15 16:25,约887字,阅读约2分钟1 概述 待完善。。。
2 配置方式 2.1 RegionServer 不推荐:原因是不够灵活。
hbase.regionserver.region.split.policy1。默认配置org.apache.hadoop.hbase.regionserver.SteppingSplitPolicy2。
<property> <name>hbase.regionserver.region.split.policy</name> <value>org.apac ...2022-01-16 09:50,约915字,阅读约2分钟KeyValue12是HBase的最底层的核心存储结构,也是数据最终格式持久化的格式。这里分析一下格式细节。
1 概述 一个KeyValue代表着一行数据中的具体的某一列。比如你的一行数据有10列,那么最终会有10个KeyValue存储下来(没有修改删除的情况下)。此外KeyValue只有添加操作,没有删除修改的操作。基于以上两点,使得HBase具备列一下的特性:
SchemaLess : 最小存储单元是列,所以可以不必事先定义好有那些行列结构。 版本管理:只有添加操作,删除和修改是通过新增新版本的Key ...2021-04-27 00:55,约3638字,阅读约8分钟不要感觉奇怪,为什么介绍Git的文章里面怎么会出现一个文件系统,还内容寻址,这都是什么啊?其实内容寻址文件系统(content-addressable filesystem)才是git的底层核心,而我们平时使用的commit,branch和checkout等等命令仅仅只是在上层包装成了VCS(version control system)的样子。
文件系统是用来在物理存储设备上为上层应用提供抽象的文件管理功能的。比如常见的fat、fat32、ntfs、ext4等等。
内容寻址指的是基于文件的内容来定位文件 ...2021-04-23 13:46,约2321字,阅读约5分钟基于IO模型1、Socket API2以及IO Multiplexing API3,基本上已经涵盖了目前基于网络编程的所使用的主流技术点。那么我们就可以评估一下各种组合方式所带来的 架构属性4。
通常来讲基于网络的应用都会匹配最基础的C/S风格5。这样的应用至少有两个核心组件:client和server,我们这里就关注一下这两个组件内部在运行时抽象的架构。其次网络通信的传输协议主要有UDP和TCP两个,而UDP因为其无需建立连接,所以其对于client和server而言均是无状态的,这时并不需要进行复杂的 ...2021-04-13 17:08,约3006字,阅读约6分钟在上一节Socket中介绍了socket相关的一些基础函数,以及一个基础版本的echo客户端和服务器程序,同时也遗留了一些问题1。
其中核心问题在于只能一次处理一个IO,而且IO的accept、recv、send和fgets等操作还都是阻塞的。导致应用大部分时间都是处在等待中,利用效率低下;而fork2的多线程版本又性价比不高,支撑不了太多的连接。
那么解决方案主要有两类3,这两类都可以解决著名的C10k问题4:
IO操作异步非阻塞化,称之为异步非阻塞IO。改动较大,而且异步后的通知处理是个麻烦的问题。比 ...2021-04-13 17:01,约3373字,阅读约7分钟Socket1是一套抽象的用于网络通信的API,它使得应用层可以不必关心底层繁琐的传输通信细节。
开始之前最好具备一些计算机网络2的基础,TCP3以及网络字节序4的相关知识储备。
1 基础简介 方便起见,这里假设底层是IPv4和TCP。
1.1 地址结构 既然是建立通信,那么就需要知道对方的地址。socket使用struct sockaddr_in来存储连接一方的ip和port。
typedef __uint32_t in_addr_t; /* base type for internet address ...2021-03-20 09:30,约1705字,阅读约4分钟在上一篇博客Replication1中我们构建了一个简单的主从复制架构的redis服务,利用Replication我们可以让redis提供读写分离、提供读取能力、数据备份等功能,也支持slave从鼓掌中恢复。但是如果master出现了故障,那么整Replication都会处于一个不可用的状态。这显然无法满足高可用的目标。而整个目标需要借助sentinel2来实现。
sentinel概述:
监控:sentinel是一个分布式系统,多个实例利用gossip协议协同工作。sentinel监控master和sla ...2021-03-20 09:29,约2424字,阅读约5分钟绝大多数的情况下,redis中的数据都是读取远远多于写入。为了提供更高的读取QPS的支持,所以redis提供了Replication1的支持。
单纯的Replication并不能处理redis意外宕机等导致的不可用问题。高可用需要Sentinel2来提供支持。 单纯的Replication也不能提升redis的存储容量,比如master原本是提供8G的存储上限,那么搭配两个slave则依然是8G。扩容需要Cluster3来提供支持。 1 搭建环境 这里使用docker-compose -f redis.y ...2021-03-19 20:12,约845字,阅读约2分钟redis自从诞生之处就被称之为单线程的方式实现的,这里的单线程指的是socket read、解析、执行和socket write这四个阶段都是由主线程独自完成的。当然一个redis-server实例并不是只有这一个线程,比如还有执行RDB、AOF、LRU、AOFREWRITE等等后台线程,只是它们的运行不会参与到server的主线程处理client的request这个流程中。
1 主线程 # 启动一个redis的容器,开启AOF docker run --name redis.test -d redis ...2021-03-19 20:12,约2207字,阅读约5分钟1 基本概念 redis速度非常快,但是有多块呢?首先我们需要分析一下当client发起对server的调用到获得结果这段时间内都经历了那些主要的步骤,比如如下代码:
Jedis jedis = new Jedis("localhost"); String result = jedis.set("name", "lnh"); 详细分解一下其中经历的主要步骤:
client发起调用; 初始化网络连接(或者从client端维护的连接池中获取连接); 把java ...2021-03-19 20:11,约1725字,阅读约4分钟redis是基于内存存储数据的,当server意外宕机或者重启时,内存中的数据就会丢失掉。redis提供了如下几种选项来应对不同场景下的需求。
RDB(Redis DataBase) :按照配置的时间周期来定时保存内存中的数据快照到disk上。 AOF (Append Only File) :通过记录server接收到的每一个write命令,在下次启动时重放这些指令,以此达到恢复数据的目的。 No persistence :完全禁用持久化。 RDB + AOF :同时启用RDB和AOF。这种情况下AOF优 ...2021-03-19 20:11,约1330字,阅读约3分钟redis2.6+在server端内嵌了lua1的支持,可以执行client发送的自定义的lua script,使得一些操作逻辑可以放到server上来执行,有利于减少一些不必要的网络交互,从而提升性能。在架构风格上这隶属于COD(Code On Demand)按需代码2,类似于REST3的六大架构约束之一的COD约束4,但是不同的是,这里的COD是运行在server端的。
1 命令 执行lua script的主要是EVAL5和EVALSHA6。
EVAL script numkeys key [key ...2021-03-19 19:52,约2557字,阅读约6分钟因为redis通常主要用来作为一个缓存服务。缓存何时失效的问题号称是计算机科学领域两大难题之一(另一个是命名),这一篇文章就介绍下笔者对于缓存如何以及何时失效的问题理解。
1 过期删除方式 redis支持通过两种方式清理过期的key1:
被动删除。 主动删除。 1.1 被动删除 在client访问(任意读写操作)一个key时,如果key设置了过期时间,则在访问时删除它们。如果没有主动设置过期时间,那么key则是会一直不会过期的。
1.2 主动删除 单单只有被动删除是完全不够的,当一个key完全不再会访问时 ...2021-03-19 19:51,约1077字,阅读约3分钟1 问题分析 设想一下有这样一个场景。在一个RTT1为10ms的网络环境下,循环执行一个INCR xxkey的操作,假定redis-server每次耗时1ms。
当cleint发出INCR xxkey的命令后,要等11ms后才能收到响应。如果循环100次,则总共就需要1100ms。显然redis-server执行100次仅需要1ms*100=100ms,而消耗在RTT1上所需的时间为10ms*100=1000ms。网络延迟消耗了太多的时间。
redis的基本通信模型是request/response。即 ...2021-03-19 19:50,约6007字,阅读约12分钟redis支持丰富的数据类型1。我们这里从两个角度来介绍:
client使用:client可以使用到的数据类型。 server实现:server内部的具体实现。 1 client使用 1.1 String string是一个二进制安全的字符串,类似于java的String,但是它是可以修改的。value最大长度不能超过512MB。
redis中的key是string类型的,key的命名规则的通常采用:分割的具有层级结构的形式,比如account:1001:followers。
常用命令:
SET key ...2021-03-19 13:07,约1153字,阅读约3分钟因为Redis是基于网络的分布式缓存服务,所以其隶属于客户端-服务器架构风格1。这就使得它必须通过网络进行通信,那么其客户端和服务端所采取的应用层协议为RESP(REdis Serialization Protocol)2。底层的传输协议为TCP3,端口号6379。
1 请求/响应模型 Client发送各种命令给Server,Server接收命令并处理后把响应消息发回Client。有两种例外的情况:
pipelining : Client一次性的发送多个命令。 Pub/Sub:Server会改成推送方式, ...2020-11-08 19:33,约2562字,阅读约6分钟在Java中,有一个与锁有关的关键字synchronized,它是由JVM层面提供的Monitor来实现。
1. 语法 synchronized关键字在语法层面1有两种形式。请看如下的示例代码:
SynchronizedExample.java import java.io.File; public class SynchronizedExample { public void instanceSynchronizedStatementMethod(Object syncObject) { synchro ...2020-11-08 19:32,约1405字,阅读约3分钟1 CAS(Compare And Swap) 概念和原理 CAS是Compare And Swap的缩写,中文含义是比较和交换。CAS定义了三个值:
V : 待更新的变量Var E : 预期的旧值Expected Value N : 新值New 执行过程的伪代码如下:
if(V==E){ V=N; } 也就是说只有在变量V的值等于期望的旧值时,才更新V为新值N。不然什么都不做。以此证明其他线程没有更改V的值。根据上面的伪代码来看,是不是会出现if通过了,但是在V=N的时候其他线程改了V呢?其实不会的, ...2020-11-07 19:32,约3139字,阅读约7分钟1 OS内核态进程 进程是OS进行资源分配和调度的最小单元,进程之间互相隔离,这样使得OS可以并行运行多个应用程序。OS:进程=1:N
遗留问题:这时OS可以并行多个应用程序了,但是应用程序内部则只能串行的运行。
2 OS内核态线程 为了解决进程遗留的问题,OS就创造了线程,使得一个应用程序内部也可以并行,进程:线程=1:N。Linux在默认情况下,创建一个线程需要分配8MB的栈内存空间。
# 查看默认的栈内存大小 ulimit -s # 输出,8192KB=8MB 8192 以及从用户态切换到内核态的 ...2020-11-06 19:32,约2308字,阅读约5分钟GC要解决的三个问题:
哪些对象需要回收? 何时回收? 如何回收? 1 哪些对象需要回收? Java的内存区域中,Java线程栈、本地方法栈和程序计数器因为是线程私有的,随着线程的执行自动的释放,所以这部分是是无需回收的。目前需要回收的主要是两个区域:堆和元数据区。又因为元数据区域存放的是class的信息和常量以及一些静态变量等数据,这部分的数据的生命周期通常是和Java进程保持一致的,所以回收的意义不大。故而只剩下一个区域堆。
那么在回收之前,首先要做的事情就是识别出来堆中的哪些对象是垃圾对象,目前主要 ...2020-11-05 19:32,约1573字,阅读约4分钟Java内存模型JMM(Java Memory Model)在Java中由两份规范文档定义:
JLS(Java Language Specification)的Chapter 17. Threads and Locks]1。 JSR-133: Java Memory Model and Thread Specification Revision2。JSR-133(JDK 5实现了)是对JLS中的补充和完善。 A memory model describes, given a program and an ...2020-11-04 19:32,约1710字,阅读约4分钟Unsafe类是Java提供一个底层的类型,位于sun.misc包中,主要用来提供一些不安全的底层内存操作。
其内部实现在Jdk中略有差异,比如。Jdk 81和Jdk 152的源码。
1 获取Unsafe对象 由于Unsafe在实现上添加了限制(只能由BootstrapClassLoader加载的类型来调用,而我们的代码通常都是AppClassLoader加载的),所以我们无法直接通过Unsafe.getUnsafe()这个静态方法来获取。
@CallerSensitive public static U ...2020-09-03 12:08,约2726字,阅读约6分钟记录一下笔者关于状态的一些相关认知。
1 状态 在计算机领域,状态1指的是一个系统被设计用来记住之前的事件或用户交互,那么就称之为有状态的系统,系统记录的信息则就是状态。注意这里的重点不是说记录信息,而是记住之前的。
举个例子:你去楼下的便利店买东西,95元,你给了店家100块,但是店家暂时没零钱,这时候你说了,算了,你先记着吧,下次买东西少收我5块就是了,店家说好嘞。然后第二天你又去买东西了,要求店家减免你5块钱,店家说凭什么啊。。。然后你说昨天你没零钱找我5块钱,忘了?噢噢噢,对对,不好意思啊,忘了。 ...2020-05-10 09:27,约1268字,阅读约3分钟1 Connection String mongodb://mongodb-server-1:27017,mongodb-server-2:27017/admin ?replicaSet=test-replica-set &ssl=false &w=3 &j=true &wtimeoutMS=5000 &readPreference=secondaryPreferred &readConcernLevel=local 2 Read Write Config ...2020-04-13 22:20,约523字,阅读约2分钟kubectl是k8s的command-line工具,用来管理k8s中的各种资源。kubectl是一个go编写的单文件可执行程序,支持Windows、Linux、macOS。kubectl通过HTTPS APIs和k8s的集群的API Service进行通信,使用这些APIs来提供管理功能。
1 kubectl的安装和配置 因为kubectl是一个单文件可执行程序,安装非常简单,直接下载即可(或者通过yum、apt、brew、choco等包管理器来安装)。
可以通过https://storage.goog ...2020-04-12 17:13,约1016字,阅读约3分钟1 ENTRYPOINT 推荐使用ENTRYPOINT(不要和CMD同时使用) : 当ENTRYPOINT存在时,CMD会作为它的参数存在,增加复杂性。ENTRYPOINT指令ENTRYPOINT EXEC和ENTRYPOINT SHELL两种语法形式。但是不管是那种形式,都只是dockerfile中的语法形式,实际build后的结果都是统一的JSON数组格式。
1.1 EXEC ENTRYPOINT ["executable", "param1", "param ...2020-03-31 12:15,约719字,阅读约2分钟抽象层面 : Pod = random-ip:fixed-port
1 概述 K8S中调度的最小单元。可以简单的类比:
平台 最小调度单元 KVM VM Docker Container K8s Pod 2 容器的资源限制 resources: # 资源限制 requests: # 请求的资源: k8s根据requests来进行pod的调度; HPA进行伸缩时也是根据requests来计算的。 cpu: '500m' # 单位=milli(千分之一)。50%vCPU。 memory: &# ...2020-03-04 19:32,约4569字,阅读约10分钟Java是一个跨平台的语言,当初的口号编译一次,到处运行。那么它是如何实现跨平台运行的呢?计算机领域有个有个著名的定理中间层定律:计算机科学领域的任何问题都可以通过增加一个中间层来解决。那么Java的跨平台也不例外,它就是通过添加了一个中间层来解决跨平台运行的问题的。
我们知道计算机是无法直接运行我们编写的程序设计语言1的代码的,需要编译为计算机可理解的特定底层汇编或者机器码指令才可以。所以Java从诞生之初就没有编译成平台相关的代码,而是编译为了平台无关的bytecode字节码(文件扩展名.class) ...2020-02-20 21:40,约1436字,阅读约3分钟1 基本概念 在开始前先解释两组概念。
1.1 Blocking / Non-Blocking Blocking和Non-Blocking通常指的这次操作会不会阻碍后续操作。比如在等红绿灯,或者遇上了堵车,我们通常都会说是被堵了,导致你只能在此等着,虽然你闲下来了,但是干不了后续其他事情。
1.2 Synchronous / Asynchronous Synchronous和Asynchronous通常指的是这次操作能不能立即得到想要的结果。如果可以,那就是Synchronous,否则就是Asynchr ...2020-02-20 21:20,约867字,阅读约2分钟1 NAT NAT(Network Address Translation)1 : 网络地址转换。是一种重写 IP Packet 的 Source IP 或 Destination IP 的技术,用来解决私有地址无法和外部通信的问题,也大大的缓解了IPv4的枯竭问题,同时促进了互联网的蓬勃发展。
假设原始的 IP Packet 如下 :
Source IP Destination IP 192.168.2.2 9.9.9.9 1.1 SNAT SNAT(Source Network Address Tr ...2020-02-20 20:55,约6410字,阅读约13分钟TCP(Transmission Control Protocol)是一种全双工的、面向连接的、基于字节流的、可靠的(尽最大努力交付)、有状态的 传输层通信协议。先看一TCP的数据包Segment1长什么样子,后续的各种功能都会体现在其中:
tcp.segment TCP Segment |- - - - - - - -+- - - 32 bits(4 octets) - - - -+- - - - - - - -| |0 1 2 3 4 5 6 7+0 1 2 3 4 5 6 7+0 1 2 3 4 5 ...2020-02-15 13:07,约2492字,阅读约5分钟X.509是# 公钥证书的格式标准, 广泛用于TLS/SSL安全通信或者其他需要认证的环境中。X.509证书可以由# CA颁发,也可以自签名产生。
1 Overview X.509证书中主要含有公钥、身份信息、签名信息和有效性信息等信息。这些信息用于构建一个验证公钥的体系,用来保证客户端得到的公钥正是它期望的公钥。
公钥 : 非对称密码中的公钥。公钥证书的目的就是为了在互联网上分发公钥。 身份信息 : 公钥对应的私钥持有者的信息,域名以及用途等。 签名信息 : 对公钥进行签名的信息,提供公钥的验证链。可以 ...2020-01-16 20:52,约837字,阅读约2分钟1 .gitattributes 的作用 位于Git Repo根目录的.gitattributes文件,用来为Git管理的文件配置一些属性。这些属性控制着Git管理的如下三个区域的文件。
通常主要用来统一EOL=end of line(在Windows上默认是crlf, 在Linux和macOS上则是lf)。
1.1 语法 .gitattributes是一个文本文件,每一行使用pattern匹配一些文件,然后设置对应的属性:
pattern attr1 attr2 ... 每一个属性都遵循如下4种规则进 ...2019-09-22 08:13,约3314字,阅读约7分钟1 网络层的用途 上一篇中遗留了一部分问题 : Frame的丢失、乱序和重复等等,在网络层这里其实也无能为力😂😂😂。因为网络层解决的问题重点是分组&交换中的交换问题。虽然在数据链路层有交换机这样的设备负责Frame的转发和交换,但是它其实并无法满足我们的需要,那么为什么呢?我们来看一下基于Frame的转发交换存在哪些问题先:
Frame的MAC不是真正含以上的地址 : 虽然MAC也叫做物理地址,不过它其实并不是真正的地址。我们通常意义上的地址是什么呢?比如你要给故宫博物院的院长写一封信,那么信封 ...2019-09-22 08:12,约3237字,阅读约7分钟1 数据链路层的用途 上一篇的遗留问题说到物理层仅仅提供01bit流是远远不够的,需要进行更高层的抽象。结合开篇中提到的计算机网络的核心设计理念分组&交换,这一层的用途就是分组 : 提供基于01bit流分组后的数据帧(PDU=Frame)。
2 三个基本问题 想要从下层的01比特中抽象出这样的结果,则需要解决一下的三个基本问题:
封装成帧。 透明传输。 差错检测。 2.1 封装成帧 下层物理层提供的是01bit流,想要变成分组后的帧,就需要定义起始和结束的标记。
起始标识 : SOH(Start ...2019-09-22 08:11,约620字,阅读约2分钟1 物理层的用途 上一篇中说到计算机网络 由 节点(node : 计算机、集线器、交换机或路由器) 和连接它们的 链路(link) 组成。本质上讲,网络通信就是双方互相传递信息,在计算机世界中,最本质的信息就是01这种bit,所有的通信都是基于此,那么物理层的用途就是传递这些bit信息。
传输媒体多种多样,比如同轴电缆、双绞线、光纤、无线电波等等。当物理层要向上层提供一致的01bit流时,它就要屏蔽这种底层的通道差异,这是物理层的任务。
2 基础概念 这里罗列一些比较重要的概念。
2.1 信道 简单来说 ...2019-09-22 08:10,约2763字,阅读约6分钟1969年11月美国国防部建立了一个名为ARPANET(Internet的雏形)的分组&交换网络,当前时间是2019年,50年过去了,如今的网络已经融入了社会的方方面面,其重要性不言而喻。本系列博客专注于计算机网络的核心概念和体系结构,并不涉及网络编程的概念。
1 标准化 计算机网络 由 节点(node : 计算机、集线器、交换机或路由器) 和连接它们的 链路(link) 组成。这些众多的设备之间如何通信?其中离不开各种各样的标准,标准的意义在于统一的规则,遵循相同标准的设备之间可以互联互通,从而 ...2018-12-01 10:41,约3488字,阅读约7分钟在上上一篇[OIDC in Action] 01 基于OIDC的SSO的登录页面的截图中有出现QQ登录的地方。这个其实是通过扩展OIDC的OpenID Provider来实现的,OpenID Provider简称OP,OP是OIDC的一个很重要的角色,OIDC用它来实现兼容众多的用户认证方式的,比如基于OAuth2,SAML和WS-Federation等等的用户认证方式。关于OP在[认证&授权] 04 OIDC(OpenId Connect)身份认证(核心部分)中有提到过,但是并未详细解释。
由于 ...2018-01-13 15:23,约2736字,阅读约6分钟在前面5篇博客中介绍了OAuth2和OIDC(OpenId Connect),其作用是授权和认证。那么当我们得到OAuth2的Access Token或者OIDC的Id Token之后,我们的资源服务如何来验证这些token是否有权限来执行对资源的某一项操作呢?比如我有一个API /book,它具有如下5个操作 :
POST /book : 添加一本书 GET /book/{id} : 获取一本书 PUT /book/{id} : 更新一本书 DELETE /book/{id} : 删除一本书 GET / ...2017-11-27 12:19,约2276字,阅读约5分钟在上一篇[OIDC in Action] 01 基于OIDC的SSO的中涉及到了4个Web站点 :
oidc-server.dev : 利用oidc实现的统一认证和授权中心,SSO站点。 oidc-client-hybrid.dev : oidc的一个客户端,采用hybrid模式。 oidc-client-implicit.dev : odic的另一个客户端,采用implicit模式。 oidc-client-js.dev : oidc的又一个客户端,采用implicit模式,纯静态网站,只有js和htm ...2017-11-26 01:09,约4294字,阅读约9分钟在[认证&授权]系列博客中,分别对OAuth2和OIDC在理论概念方面进行了解释说明,其间虽然我有写过一个完整的示例(https://github.com/linianhui/oidc.example),但是却没有在实践方面做出过解释。在这里新开一个系列博客,来解释其各种不同的应用场景。因为OIDC是在OAuth2之上的协议,所以这其中也会包含OAuth2的一些内容。
OIDC协议本身有很多的开源实现,这里选取的是基于.Net的开源实现基于IdentityServer4。本系列的源代码位于http ...2017-11-16 13:39,约3427字,阅读约7分钟在上一篇[认证&授权] 04 OIDC(OpenId Connect)身份认证(核心部分)中解释了OIDC的核心部分的功能,即OIDC如何提供id_token来用于认证。由于OIDC是一个协议族,如果只是简单的只关注其核心部分其实是不足以搭建一个完整的OIDC服务的。本篇则解释下OIDC中比较常用的几个相关扩展协议,可以说是搭建OIDC服务必备的几个扩展协议(在上一篇中有提到这几个协议规范):
Discovery : 可选。发现服务,使客户端可以动态的获取OIDC服务相关的元数据描述信息(比如支持 ...2017-10-21 15:21,约7290字,阅读约15分钟衔接上文[理解REST] 05 Web的需求 & 推导REST,上文根据Web的需求推导出了REST架构风格,以及REST的详细描述和解释。自从1994年以来,REST架构风格被用于指导Web架构的设计和开发工作,最重要的两点体现在设计HTTP和URI两个互联网规范协议的过程中,以及实现这些规范的libwww-perl客户端库,Apache HTTP项目(httpd)以及其他的实现中,所得到的经验以及教训。
其实REST也用于指导约束超媒体的设计工作,比如HTML,但是Fielding并未在论文中 ...2017-09-24 13:33,约7230字,阅读约15分钟衔接上文[理解REST] 03 基于网络应用的架构,上文介绍了一组自洽的术语来描述和解释软件架构;如何利用架构属性评估一个架构风格;以及对于基于网络的应用架构来说,那些架构属性是值得我们重点关注评估的。本篇在以上的基础上,列举一下一些常见的(REST除外)的适用于基于网络应用的架构风格,并使用对比架构属性的方式对其进行评估。
1 架构风格所产生的架构属性 架构设计的目的是为了满足或者超出应用的需求,而不是为了创造出一种特殊的交互拓扑或者一种特殊的设计方式。当设计一个系统时所选择的架构风格,必须与这些需求保 ...2017-09-17 16:58,约4756字,阅读约10分钟链接上文[理解REST] 02 REST是用来干什么的?,上文中解释到什么是架构风格和应该以怎样的视角来理解REST(Web的架构风格)。本篇来介绍一组自洽的术语,用它来描述和解释软件架构;以及列举下对于基于网络的应用来说,哪些点是需要我们重点关注的。
1 软件架构 软件架构方面关注的是如何以最佳的方式划分一个系统、如何标识组件、组件之间如何通信、信息如何表达、组成系统的元素如何独立的进化,以及如何表达上述的内容。一个优秀的软件架构并非凭空靠想象得来的,每一个架构级的决策,都应该根据被设计的系统功能、行为 ...2017-09-15 23:24,约2173字,阅读约5分钟衔接上文[理解REST] 01 REST的起源,介绍了REST的诞生背景。每当笔者遇到一个新事物的想去了解的时候,总是会问上自己第一个问题,这个新事物是干什么用的?在解释我所理解的REST这个过程中也不例外,这篇博客我们先关注一下REST是干什么用的,然后后续再解释REST是什么。好了,不说废话了,在上篇结尾处说到,REST是Web的架构风格,暂且不管REST和Web,我们先看看架构风格是什么东西?
1 什么是架构风格? 计算机科学中,架构(Architecture)一词来源于建筑学,我相信大家在不少资料 ...2017-09-06 10:06,约2348字,阅读约5分钟1 世界上第一个网站 1990年12月20日,这一天对于现在的互联网来说意义非凡。欧洲核子研究组织(CREN)的科学家Tim Berners-Lee在一台NeXT电脑上启动了世界上的第一个网站(当然当时仅能Tim Berners-Lee自己访问),这台电脑至今仍保留在CREN,但当年那个网站已经不复存在了。鉴于这个网站的意义重大,CREN在2013年 “复刻” 了这个网站,并指向了原来的网址 : http://info.cern.ch 。由于现在的浏览器早已不是当初的样子,所以CREN还提供了一个模拟器 ...2017-07-23 14:24,约2464字,阅读约5分钟在信息安全领域,一般把Cryptography称为密码,而把Password称为口令。日常用户的认知中,以及我们开发人员沟通过程中,绝大多数被称作密码的东西其实都是Password(口令),而不是真正意义上的密码。本文保持这种语义,采用密码来代指Password,而当密码和口令同时出现时,用英文表示以示区分。
1 OTP 一次性密码 OTP是One Time Password的简写,即一次性密码。在平时生活中,我们接触一次性密码的场景非常多,比如在登录账号、找回密码,更改密码和转账操作等等这些场景,其中一 ...2017-07-04 22:25,约1537字,阅读约4分钟1 简单回顾 在前面两篇博客中介绍了密码相关的一些基本工具,包括(对称密码,公钥密码,密码散列函数,混合密码系统,消息认证码,数字签名,伪随机数,数字证书)这几个。其中它们之间也是互相依赖的,我们来简单的梳理一下它们的依赖关系。
对称密码 : 无。 公钥密码 : 无。 密码散列函数 : 无。 伪随机数 : 可以利用[密码散列函数来]实现,也可以不使用。 混合密码系统 : 对称密码 + 公钥密码 + 密码散列函数。 消息认证码 : 密码散列函数 + 对称密码。 数字签名 : 密码散列函数 + 公钥密码。 ...2017-07-02 15:08,约5006字,阅读约10分钟在上一篇[信息安全] 01 密码工具箱 第1部分中介绍了一些密码技术相关的一些基本工具,同时遗留了一个鸡生蛋蛋生鸡的问题和公钥的认证问题( ̄▽ ̄)",这里再补充几个常用的工具先。
1 伪随机数(Pseudo-Random Number) 随机数大家不陌生,但是随机数怎么就和信息安全扯上关系了呢?其实想一想我们在给自己的账号设置密码的时候,是不是都会尽量的让其他人不会轻易的猜到我们的密码,虽然并不是随机,但是它就像是满足了随机数的一个特征 : 不可预测性。那么对于信息安全来说来说,也是用到了这个特 ...2017-06-26 22:55,约9587字,阅读约20分钟0 何谓信息安全? 对于信息安全性的重要性,我想大家都不会否认。那么具体来说应该具有哪些特性才能称之为安全呢?举个简单的例子 : 我给你发送一条消息"借给我100元",当你收到这条消息并且处理后你的账户里面会少出来100块,我的账户会多出来100块。在这个过程中,你是消息接收方,我是消息发送方。
作为通信双方的你我都不希望让其他人能读懂这条消息。这是信息的机密性 : 即消息在传递过程中不被其他人解读。 作为通信双方的你我都不希望消息内容变成"借老子1000块!"( ...2017-04-09 16:59,约6611字,阅读约14分钟原作者 : Justin Richer, 原文: User Authentication with OAuth 2.0。
OAuth2规范定义了一个授权(delegation)协议,对于使用Web的应用程序和API在网络上传递授权决策非常有用。OAuth被用在各钟各样的应用程序中,包括提供用户认证的机制。这导致许多的开发者和API提供者得出一个OAuth本身是一个认证协议的错误结论,并将其错误的使用于此。在此需要明确指出 :
OAuth2不是认证协议。 OAuth2不是认证协议。 OAuth2不是认证协议 ...2017-04-03 03:56,约4390字,阅读约9分钟1 RFC6749还有哪些可以完善的? 1.1 撤销Token 在上篇[认证&授权] 01 OAuth2授权中介绍到了OAuth2可以帮我们解决第三方Client访问受保护资源的问题,但是只提供了如何获得access_token,并未说明怎么来撤销一个access_token。关于这部分OAuth2单独定义了一个RFC7009 - OAuth 2.0 Token Revocation来解决撤销Token问题。
1.2 Token对Client的不透明问题 OAuth2提供的access_toke ...2017-02-06 16:34,约552字,阅读约2分钟Tilde Expansion ~ ~ : /home or /users or /Users.
# user 'lnh'. # /home/lnh/.bash_profile or /users/lnh/.bash_profile echo ~lnh/.bash_profile # current user home directory echo ~ Brace Expansion {} # a b c echo {a..c} # 01 02 03 04 05 06 07 08 09 ...2017-01-09 09:40,约7146字,阅读约15分钟1 OAuth2解决什么问题的? 举个栗子先。小明在QQ空间积攒了多年的照片,想挑选一些照片来打印出来。然后小明在找到一家提供在线打印并且包邮的网站(我们叫它PP吧(Print Photo缩写 😂))。
那么现在问题来了,小明有两个方案来得到打印的服务。
在自己的QQ空间把想要打印的照片下载下来,然后提供给PP(直接发邮件给PP或者网盘共享给PP等等)。 把自己的QQ账号密码给PP,然后告诉PP我要打印哪些照片。 针对方案(1) : 小明要去下载这些照片,然后给PP,小明累觉不爱,,,
针对方案(2) ...2017-01-06 16:34,约176字,阅读约1分钟1 Command Option Parameter # 查看版本 bash --version # show the current shell. echo $SHELL # displays all installed shell. cat -n /etc/shells command : cat option : -n parameter : /etc/shells 1.1 Command Pipeline Looping Conditional Grouping 1.2 Parameter Ch ...2015-05-09 16:01,约12826字,阅读约26分钟0 概述 为何高级语言需要类型系统这个概念?在汇编时代是没有完整的数据类型系统的,结构化编程引入了结构化的控制流、为结构化设计的子程序,随之这种结构化的代码所操作的数据也进一步的抽象化、特化,故而有了数据类型这种概念,类型系统主要用于两个用途 :
为许多操作提供了隐含的上下文信息,使程序员可以在许多情况下不必显示的描述这种上下文。比如int类型的两个对象相加就是整数相加、两个字符串类型的对象相加就是拼接字符串、C#中new object()隐含在背后的就是要分配内存返回对象的引用等等。 类型描述了其对象 ...2014-08-27 09:30,约16495字,阅读约33分钟0 概述 前面介绍了语言的演进以及一些基础概念后,从本篇开始进入了语言的核心问题中。这一篇讨论的是语言计算模型(大致可以用控制流来表述),大致如下7种 :
顺序执行 : 最基本的流程控制,按部就班的一条一条按顺序执行; 选择 : 根据运行时的某些条件来决定执行那些,如if else等; 迭代 : 反复(或特定次数)的执行一段代码,如for循环; 过程抽象 : 把一段代码抽象成一个简单的过程单元,用来完成某项特定的代码逻辑; 递归 : 一个表达式直接或者间接的调用自身; 并发 : 两个或更多程序片段同时( ...2014-08-03 09:09,约8021字,阅读约17分钟1 名字、约束时间(Binding Time) 在本篇博文开始前先介绍两个约定:第一个是对象,除非在介绍面向对象语言时,本系列中出现的对象均是指任何可以有名字的东西,比如变量、常量、类型、子程序、模块等等。第二个是抽象的,因为我们讨论的是语言的核心概念,所以抽象的具体指代的是语言特征与任何计算机体系结构分离的程度。
如果可以给名字下个定义,那么它是代表某东西的一些助记字符序列。就好比张三、李四,对应到大部分语言中一般可以等价为标识符。名字可以让我们用一个符号来表示变量、子程序、类型等等,其实名字就是一种 ...2014-07-20 19:58,约2671字,阅读约6分钟1 机器语言 > 汇编语言 > 高级语言 语言是人与人的一种交流工具,就比如我现在用汉语来写这篇博文来交流探讨技术问题;程序设计语言也是如此,只是交流对象不是人而是机器。我可以用汉语来写博文,也可以用英语来写(假如我英语熟练);我可以用PHP来写一个网站,也可以用ASP.NET来写。这就说明语言的本质就是一种交流工具,而我选择哪种语言来交流并不会影响我要的结果。然而在实际中到底要选用那个语言确要根据具体情况而定,这是个成本问题,比如我如果今天脑子抽筋要用日语,那我写着也累(关键是也不会)、读 ...2014-07-13 09:04,约754字,阅读约2分钟1 为何要读这本书? 首先这是一本介绍语言的入门书籍(笔者阅读是裘宗燕老先生翻译的第二版),如果你想从中学到一些独门绝技,那么抱歉,木有;其次它介绍的是程序设计语言的一些重要基础概念、各种概念之间的关系;并解释了语言中诸多结构的形成和发展过程,以及他们演化到今天这种形式的根源。
那么或许你该问了,了解这些有甚好处,不知道我照样写出漂亮的代码、架构等。的确,你可以的,现在的程序员在工作中都不止要用到一两种语言,然而我们通常对这门语言最直接的感触就是它的语法层面;我猜测你或多或少都有被语法的糖衣炮弹(语法糖 ...