架构设计
孔令宽
从事安卓、前端富客户端、java后台、netty的开发和研究
展开
-
吐血加死一窝脑细胞--记录vertx3版本框架bug发现和解决策略
场景:http流代理精力和代价: 三天一夜 无数调试和尝试问题发现:对于tomcat等目标服务器,如果尝试用post文件流的形式尝试访问一个简单的get请求的小文件,比如localhost:8080/tomcat.png,现象会是怎样呢?尝试如下过程得出结论:1 通过postman发起一个大文件流给tomcat,可以立马得到响应,多次发起多次响应没任何问题,看不出任何端倪,监控磁盘也没有发现有大的磁盘IO,初步结论,tomcat不会收取大文件流2 通过自己写httpclient post一个原创 2020-09-20 12:16:08 · 494 阅读 · 0 评论 -
公众号开发要点流程设计思路总结
1 授权方案场景:一个公众号的多个菜单可能对应后端多个不同的服务(多个服务是物理分离的)问题点: 微信公众平台要求code授权回调地址只能是一个特定的域名或者路径,最多能配置两个,如果多个服务分布在不同的域名下,只能由其中一个接收授权code解决方案,做一个公共的授权码转发服务,不同域名下授权码接收接口通过授权码转发服务来转发,即 二次重定向方案,把微信重定向url中的code参数以及state参数重新拼接到目的重定向接口后进行二次重定向即可。2 授权回调接口发起的时机问题场景: 发起时原创 2020-05-09 08:50:15 · 2457 阅读 · 1 评论 -
源码分析方法
前言: 人可以不聪明,但是必须掌握做事的方法,方法论就是经验者总结出来的做某件事的通用规律和策略。本篇讲解分析源码和框架方法论,有了合适的方法论做为指引,外加自己刻苦和努力,相信世上无难事,分析源码会事半功倍。我所总结出来的源码分析方法其实很简单,总结而来就是:静态分析+动态分析 。其中,静态分析就是对代码的未执行阶段进行分析。说白了,就是分析一个工程的源码期,不涉及代码在执行阶段的表现。...原创 2020-02-24 00:51:54 · 1530 阅读 · 0 评论 -
从spring到springcloud脉络梳理(1) 开篇
随着spring系列框架发展的越来越好 越来越快 个人觉得有必要梳理一下核心脉络 首先虽然我有很多年工作经验 但是从来没有系统的学习过spring系列的框架 甚至没有看过一本完整的书籍 以前的时代 感觉spring用用就够了 但是现在时代的发展 从springboot 到 springcloud 框架越来越复杂 用的地方也越来越多 没有系统的梳理一下spring系框架 应用起来越来越捉...原创 2020-02-23 21:50:00 · 276 阅读 · 0 评论 -
跟我学代码架构设计模式之--瘦API和胖API
“胖瘦API”名词是我自己起的,用来表达如下的含义:瘦API是单纯的等待被调用的一个函数代码片段,瘦API一旦被调用就做为当前线程执行的代码片段执行,执行完毕后API的生命周期就结束了,瘦API不涉及多线程的切换。胖API也可以说成是客户端API,通常指的是一种作为控制器、调度器、门面的一种API,这种API底层通常会有自己的线程池和业务类完成复杂的任务,或者说这种API带有底层引擎支持,...原创 2019-01-20 00:25:57 · 393 阅读 · 0 评论 -
跟我学代码架构设计模式之--服务高并发高吞吐架构设计基本原理
首先我说的设计是指的最大限度提高单机单节点的服务吞吐和并发。我们设计一个服务器程序,自用户层->业务实现层->操作系统层,我们要明确的前提或限制有如下:1 服务程序要保证高吞吐量!服务程序要为用户服务,应该尽可能多的接收和处理用户的业务处理请求2 对于每个业务处理,业务层面的等待和阻塞不可以避免!(因为业务上获取任何资源数据都是需要时间的,比如数据库访问)3 在操作系统...原创 2019-01-26 10:45:40 · 492 阅读 · 0 评论 -
跟我学代码架构设计模式之--谈网络协议的设计和吞吐量的关系
首先谈几个名词: 协议设计 、IO阻塞与非阻塞、业务阻塞与非阻塞、协议处理吞吐量首先,IO的阻塞与非阻塞其实和协议的设计没有任何关系,任何协议,包括HTTP协议其实都可以设计为IO阻塞模型和非阻塞模型,比如传统的servlet模型就是IO阻塞模型,如果抛弃servlet,用NIO的多路复用完全可以实现一个IO非阻塞的HTTP协议模型。业务的阻塞非阻塞指的是业务层面上是不是需要用户等待结果的...原创 2019-01-16 16:01:22 · 303 阅读 · 0 评论 -
跟我学代码架构设计模式之--高并发高吞吐模型演变
高并发、高吞吐是我们追求的目标,最大化压榨单机的性能来达到更多更快的服务。首先说下,为什么会有这么多模型演变,本质原因是因为操作系统底层提供的线程模型不够牛逼,不能满足我们的服务需求!模型演变如下:第一代:操作系统线程无限开模型基本原理是业务请求来了以后直接开启一个线程进行后台处理,业务中包含阻塞等待的时候,直接挂起操作系统线程。这种模型的缺点是明显的,本质原因是操作系统的线程...原创 2019-01-27 11:21:47 · 418 阅读 · 0 评论 -
跟我学代码架构设计模式之--高并发服务器应用层协议栈设计要点
要设计一个高并发的服务器,应用层协议栈应该满足如下设计思路:协议栈要分成底层、中层、和高层,线程要分为IO线程和业务线程:一、底层连接要采用NIO多路复用、事件通知二、中层要完成原始TCP数据流到业务层消息的协议编解码三、高层负责上层业务消息分发和收集(读和写)要完成:提供上层读写API和事件通知、提供底层连接状态获取相关的API 提供IO线程和业务线程之间的切换,比如读AP...原创 2019-01-16 16:53:55 · 256 阅读 · 0 评论 -
跟我学代码架构设计模式之--异步编程拥塞控制
前言:传统同步阻塞编程模型中,我们最关注的问题是线程不够用,即没有充分利用计算资源,到了异步编程模型中,我们的线程资得到了充分的利用,但是我们要开始关心内存资源问题了,所以我们要在设计系统的时候做好拥塞控制,避免内存OOM的发生。这里额外的说一下:一说到同步异步编程,我们很容易的和IO尤其是socket的阻塞非阻塞联系起来,原因是明显的:传统的同步编程模型,阻塞线程的部分基本都是做IO的时候导...原创 2019-01-29 10:57:45 · 194 阅读 · 0 评论 -
跟我学代码架构设计模式之--命令式编程和流式编程区别分析
随着计算机技术的发展,传统的命令式编程方式在解决某问题上变得捉襟见肘,流式编程有着天然的异步属性,适合用在做IO等高高吞吐量的场景下,本文我来简单分析下两种编程模型的区别。 一、数据驱动方式不同命令式编程是业务代码驱动数据的方式,即数据的流动是我们的业务代码主动驱动的。一旦没有业务代码驱动,数据是不会流动起来的。我们也可以理解为数据"拉"模型,我们的业务要主动的取数据来完成业务计算和数据加...原创 2019-01-29 16:09:21 · 573 阅读 · 1 评论 -
跟我学代码架构设计模式之--命令式编程、流式编程、异步、同步、阻塞非阻塞概念理论大一统
一直以来各种编程概念充斥于耳-命令式编程、流式编程、函数式编程、异步编程、同步编程、阻塞编程、非阻塞编程、reactor模型、、潜意识里我总觉的这些概念之间有关联又没有关联的样子,今天我总于有所领悟----它们之间是围绕着一个理论基础的!!!即---数据推拉模型的不同!!! 看本文之前请先看我上篇文章,我的观点如下:首先命令式编程是数据“拉”模型,我们的业务代码要负责数据的拉取,然后处理,...原创 2019-01-29 16:56:01 · 328 阅读 · 0 评论 -
系统设计之万般皆组件思想
任何系统,都是服务于业务的,所有的业务最终都会被实现为组件,组件可以体现为一个类、一个代码模块、一个包等等。首先我们要分清楚对象实例和类的关系:1 对象对象是和系统的线程模型等架构设计紧密相关的。在系统运行过程中,可能会有许许多多的线程,此外不同的系统的线程模型也不一样,比如有的系统采用单线程reactor模型,这种模型为了保证系统的高吞吐量,可能一个对象只会关联到一个线程来避免多线程...原创 2019-02-15 14:53:31 · 274 阅读 · 0 评论 -
跟我学代码架构设计模式之--再次理解同步IO和异步IO
先虚拟一个硬件IO的例子做比喻:1 同步IO:有这么一个硬件设备,该设备可以用来存储数据,但是设备本身不具备自己的CPU,所有的数据读写操作都只能靠计算机的主CPU来完成,这样的读写相对与主CPU来说就是同步IO。2 异步IO:有这么一个设备,该设备可以用来存储数据,和1中不同的是,该设备具备自己的CPU,具有一定的自主性,当设备的数据可读时可以向主CPU发送事件通知来完成读,当主CPU将...原创 2019-01-29 21:31:15 · 243 阅读 · 0 评论 -
JAVA执行jar的两种方式的区别
1 java -jar方式2 java -classpath方式上面两种方式不能共存,即不能在指定jar参数的时候又指定classpath参数,原因如下:在没有指定自定义类加载器的情况下,两种方式的类加载器都是AppClassLoader,对于第一种方式:AppClassLoader只会在jar参数指定的jar包中的MANIFEST.MF文件中加载类和依赖jar:Main-...原创 2019-02-13 11:59:10 · 1134 阅读 · 0 评论 -
跟我学代码架构设计模式之--从操作系统到应用层面看如何高并发
一、应用层使用操作系统层面的多线程来做高并发通过线程和定时器实现任务切换。本源思想是每个线程执行一个业务代码1 业务代码阻塞的时候业务代码主动让出CPU2 通过硬件定时器中断CPU,强制剥夺线程的CPU执行权缺点:应用程序使用这种方式来高并发必须要开N多个线程,虽然通过业务让出CPU执行并没有浪费CPU时间,但是操作系统层面每个线程都维护了一个线程上下文:首先,每个线程...原创 2019-01-08 10:59:06 · 436 阅读 · 0 评论 -
跟我学代码架构设计模式之--简单的对象和线程关联关系分析要点
并发编程尤其是异步并发编程,脑中必须要有对象在内存中的清晰分布图景以及对象和线程的关联关系分布图景。要想掌握异步编程,我的观点是:要以业务对象为中心,分析对象和线程的关联关系!!!!!!!!!因为即使是异步多线程编程,最终的业务流程流转也是以对象为中心的,比如说多线程间消息的交互,本质上也是对象间的相互作用!根据我的总结,一般需要掌握如下几点关系:1 对象的创建者是哪个线程。2...原创 2019-01-13 13:46:09 · 265 阅读 · 0 评论 -
跟我学代码架构设计模式之--分布式系统的本质
首先,分布式系统也是计算机软件应用系统。那么一个计算机软件系统普遍应该有哪些部分组成呢?1 计算资源,体现在系统中就是线程资源,线程池。2 存储资源,体现在系统中就是内存存储或者磁盘存储。3 连接器,即socket,几乎所有的对外提供服务的系统,都通过socket和外部系统打交道。4 共享数据资源,这里的共享数据资源指的是用来协调其他资源的配置信息等,在非分布式的系统中,一般共...原创 2019-01-03 11:19:52 · 184 阅读 · 0 评论 -
跟我学代码架构设计模式之--对连接(Connection)和服务能力的探讨
问题的引入:很多服务的访问都是需要客户端带有连接池来访问的,比如jdbc连接数据库、MQ客户端连接队列服务器、甚至浏览器访问web服务器。很多人只是知道使用连接池保持多个连接能够提高吞吐量,但是没有一个更详细的概念,这里我来分析下这个问题。Connection是什么?其实连接就是一个双向联通的管道,在管道至上可以横切放置很多的协议编解码器,也就是我们所说的协议栈。我们可以把连接比做...原创 2018-12-27 11:30:02 · 354 阅读 · 1 评论 -
跟我学代码架构设计模式之--连接池的设计思路1
为了提高客户端程序的并发,减少线程等待时间,通常会选择使用连接池:因为建立TCP连接的过程是需要经过多次握手的,这个过程是需要业务线程等待的。采用连接池预先建立几个连接的方式来提高程序并发。重要的一点:连接池的设计其实是和应用层协议的设计紧密相关的,目前的应用层协议基本可以分为两种时序类型:1 请求--接收响应--下一个请求-下一个响应...类型,典型的协议是HTTP1.X、JDBC...原创 2018-12-27 21:37:46 · 630 阅读 · 0 评论 -
跟我学代码架构设计模式之--我的同步异步一统理论
我在这里提出一个独特的观点来统一异步和同步的概念,即:异步也归入了同步,异步只是同步的一种情况,只是因为既定约束条件的不同导致了同步和异步的区分。话不多说,直接出我的定义:所谓同步是指:为了在既定约束条件下获得正确的预期结果、多个自主的角色、随时间变化、为了访问共享的资源、而必须满足的访问时序!1 既定约束条件:直接举个例子:我希望客户端发起请求后在限定的等待时间内得到响应、我希望客户...原创 2018-12-28 09:53:18 · 167 阅读 · 0 评论 -
跟我学代码架构设计模式之--独特的视角分析程序模块依赖关系
# 当前几乎所有的程序都是按照模块化的思想设计的,比如java的一个jar可以看做一个独立的模块,nodejs的一个带有package描述文件的包可以看做一个模块,linux的一个so库可以看做一个模块,windows的dll可以看做模块。# 一个程序一般是由一个主模块,若干个被依赖的模块做为一个完整的程序(递归边界思想)。其中被依赖的模块也可能会有本身依赖的其他模块,最终一个完整的程序可以看...原创 2018-12-28 22:21:22 · 454 阅读 · 0 评论 -
跟我学代码架构设计模式之--关于对等分布式计算模型的设想
先说明下,我自己也没有专门研究过分布式计算相关的详细资料,这里我只是给出我对分布式计算的一种设想模型。首先,要想做分布式计算,我认为应该有如下几点要求:1 利用函数式编程的思想,把计算逻辑封装成“流式函数管道”或者说“计算流”,这个流设计为接收消息作为唯一的输入,流内部可以有状态数据,流中的函数在执行过程中可以改变流内部的状态数据作为计算的中间结果,函数流执行完毕后返回唯一的输出。根本原则...原创 2019-01-03 15:44:31 · 405 阅读 · 0 评论 -
跟我学代码架构设计模式之--初识函数式编程
一直一来,总把面向对象编程思想奉为圣经,直到今天在网上接触了函数式编程思想,乍看烧脑,格格不入的感觉,后经大脑高负荷运转了大半天来思考,终于有些头绪:函数式编程是和传统面向对象编程是解决问题的两种不同计算思路,用函数式编程思想对并发和分布式计算应该会很有用武之地。下面说一说我对函数式编程思想的初步理解。先从传统面向对象思想说起:面向对象思想解决问题的思路很直观,其实就是传统C语言中提出的"...原创 2018-12-29 16:31:57 · 279 阅读 · 0 评论 -
跟我学代码架构设计模式之--锁和线程
上篇讲到锁可以用来解决多线程同时访问同一资源时的同步问题,即锁可以控制多线程对函数关联资源的的同步访问。这一篇我来简单分析下锁如何解决同步问题的。在讲锁之前,我们我们先来讨论下wait和notify方法,这两个方法是用来控制线程执行的。说白了就是控制线程状态的流转,wait控制线程本身挂起等待到某个对象的阻塞队列中,线程由就绪或执行态转换成等待状态;notify方法是用来通知某个挂起阻塞队列中...原创 2018-12-25 12:18:53 · 119 阅读 · 0 评论 -
跟我学代码架构设计模式之--协议栈的设计思路
如何理解协议栈?协议栈简单的说就是对业务数据进行层层封包和层层解包的过程。发送数据的处理过程就像数据流入一个管道进行层层封包过滤,收数据的过程就像数据经过另一个管道进行层层解包过滤,管道中有一层层的过滤器,像堆叠起来的栈~如何设计协议栈?其实很简单,单独拿出协议栈中的一层过滤器,只需要考虑以下几点就可以。发送:1 考虑本层应该按何种方式接受上层的数据?上层应该传给流包,还是大小...原创 2018-12-25 12:50:48 · 1102 阅读 · 0 评论 -
跟我学代码架构设计模式之--锁和线程的补充
本文讲讲对理解锁和线程有帮助的一些零散的点~# 再思考线程的本质首先理解一点:线程会阻塞,CPU永远不会阻塞,除非电脑休眠!CPU一直在循环的忙碌执行指令,不会阻塞!在CPU的角度上看,线程其实就是一个个的数据对象!这个数据对象包含了CPU要执行的代码的CPU寄存器(包括堆栈位置相关的寄存器)信息,也就是线程上下文信息,另外还应该包含线程相关的一些状态数据,比如优先级和线程状态等!我...原创 2018-12-26 11:18:10 · 140 阅读 · 0 评论 -
跟我学代码架构设计模式之--函数式编程真的无状态吗?
佛说:一花一世界 一叶一菩提,一朵花一片叶里面可能又是一片我们未知的小天地,我们人类可能只是宇宙中的一粒尘埃,整个宇宙可能是递归的,我们只在人类社会这个递归边界上思考和探索着世界。函数式编程真的无状态吗?我的答案是:函数式编程和面向对象编程一样,只是一种编程思想和理念,函数式编程只在一定的递归边界(范围)内保持函数或者业务的无状态性。函数式编程对于解决高并发问题是一种从理念上相当理想的...原创 2019-01-02 11:28:11 · 500 阅读 · 0 评论 -
跟我学代码架构设计模式之--函数式编程和高阶函数和流式编程
道曰:形而上者谓之道。在事物的所有表象之外,必然有一种根本统治着它们--道。上篇两篇我对函数式编程有了初步的分析,这一篇我尝试分析下如何使用函数式编程思想来实现业务逻辑。一、根本思想用函数式思想来解决问题的根本原理就是:1 一个函数接收参数 2 进行业务处理 3生成返回值 4 将返回值传递给下一个函数,下一个函数继续上面的1-4步骤,多个函数组合来完成业务,通过参数传递传递初始数据或者...原创 2019-01-02 16:45:52 · 415 阅读 · 0 评论 -
跟我学代码架构设计模式之--孔氏并发定理
前言:并发的根本是减少线程阻塞等待的时间,有两种阻塞:一种是业务上的代码架构设计导致的状态共享加锁导致的阻塞一种是对特定资源的等待导致的阻塞。只有同时避免了两种阻塞等待,才能达到真正的并发最大化!一、如何取消状态共享锁导致的阻塞。角色:特定时间段、 线程、状态(只读状态数据、可脏写状态数据、安全状态数据)状态指的是堆区数据,按业务特征可以分为:只读状态数据、可脏写状态数...原创 2019-01-12 11:37:02 · 217 阅读 · 0 评论 -
跟我学代码架构设计模式之--MQ和RPC的本质区别
有人说RPC是用来做同步通信的,MQ是用来做异步通讯的,这个认为观点不太准确。观点如下:1 RPC在协议设计上和传输层通信上完全可以设计为异步非阻塞的高性能通讯模式,甚至完全可以采用和MQ使用相同协议和传输层设计来实现RPC调用。2 MQ也可以实现同步的请求响应模式的通讯。所以,用同步和异步通信方式来区分MQ和RPC是不准确的。那么,MQ的真正价值在哪里呢?答案是:解耦!...原创 2019-01-03 00:42:01 · 2817 阅读 · 1 评论 -
跟我学代码架构设计模式之--Lock和Condition
# Condition和JDK中的Object类的wait、notify方法一样是控制线程状态的,使用Condition的前提也是必须要先获得锁对象。# 之前的博文分析过锁,这里先来总结下锁释放的几种方式:1 调用锁的unlock等方法手动释放锁2 线程异常退出的时候虚拟机自动释放锁(有些锁可能不会自动释放)3 调用Condition类的await来使线程等待并释放锁由于使用C...原创 2018-12-26 16:43:51 · 206 阅读 · 0 评论